revise readme. add example again.
This commit is contained in:
parent
76d8156fd3
commit
00975732a7
482
README.md
482
README.md
@ -25,20 +25,9 @@ letting people I don't know maintain this library due to its importance.
|
||||
|
||||
## Building
|
||||
|
||||
### bitcoind
|
||||
### libbitcoind.so
|
||||
|
||||
Cloning libbitcoind:
|
||||
|
||||
``` bash
|
||||
$ cd ~
|
||||
$ git clone git://github.com/bitpay/bitcoin.git libbitcoind
|
||||
$ cd libbitcoind
|
||||
```
|
||||
|
||||
This is a fork of bitcoin v0.9.0 right now, but it has the ability to compile
|
||||
bitcoind as a shared object. This may not be ideal yet.
|
||||
|
||||
#### Compiling bticoind as a library
|
||||
#### Compiling bitcoind as a library
|
||||
|
||||
##### Dependencies
|
||||
|
||||
@ -56,28 +45,25 @@ bitcoind as a shared object. This may not be ideal yet.
|
||||
|
||||
- secp256k1
|
||||
|
||||
##### Building
|
||||
|
||||
``` bash
|
||||
# ensure clean up
|
||||
$ make clean
|
||||
$ git clean -xdf
|
||||
|
||||
# create configure file
|
||||
$ ./autogen.sh
|
||||
|
||||
# configure as a library with -fPIC on all object files
|
||||
# use --with-incompatible-bdb if necessary
|
||||
# use --prefix=/usr if necessary
|
||||
# osx users may have to specify a boost path
|
||||
$ ./configure --enable-daemonlib --with-incompatible-bdb
|
||||
|
||||
# build libbitcoind.so
|
||||
$ time make
|
||||
real 31m33.128s
|
||||
user 16m23.930s
|
||||
sys 2m52.310s
|
||||
$ cd ~/node_modules/bitcoind.js
|
||||
$ ./build-libbitcoind.sh remote
|
||||
```
|
||||
|
||||
`remote` will clone the latest bitcoin upstream, apply a patch to it, compile
|
||||
libbitcoind.so, and place it in the appropriate directory. The first argument
|
||||
can also be a bitcoin repo directory you already have on your disk, otherwise
|
||||
it will check for ~/bitcoin by default.
|
||||
|
||||
NOTE: libbitcoind.so is currently unsupported on OSX due to OSX's mess of
|
||||
header files and libraries. Special magic is required to make this work that
|
||||
has not been implemented yet. This will only compile on a real unix (linux is
|
||||
recommended).
|
||||
|
||||
###### In the build-libbitcoind.sh script:
|
||||
|
||||
`--enable-daemonlib` will compile all object files with `-fPIC` (Position
|
||||
Independent Code - needed to create a shared object).
|
||||
|
||||
@ -88,7 +74,7 @@ compiling tests and the QT object files.
|
||||
Without `--enable-daemonlib`, the Makefile with compile bitcoind with -fPIE
|
||||
(Position Independent for Executable), this allows compiling of bitcoind.
|
||||
|
||||
### bitcoind.js:
|
||||
### bitcoind.js
|
||||
|
||||
``` bash
|
||||
$ cd ~/node_modules/bitcoind.js
|
||||
@ -106,10 +92,10 @@ bitcoind: status="start_node(): bitcoind opened."
|
||||
[should see full javascript blocks here]
|
||||
```
|
||||
|
||||
However, if you look at the bitcoind log files:
|
||||
You can also look at the blocks come in through the bitcoind log file:
|
||||
|
||||
``` bash
|
||||
$ tail -f ~/.bitcoin/debug.log
|
||||
$ tail -f ~/.libbitcoind-example/debug.log
|
||||
```
|
||||
|
||||
^C (SIGINT) will call `StartShutdown()` in bitcoind on the node thread pool.
|
||||
@ -120,19 +106,34 @@ bitcoind.js has direct access to the global wallet:
|
||||
|
||||
``` js
|
||||
var bitcoind = require('bitcoind.js')({
|
||||
directory: '~/.libbitcoin-test',
|
||||
testnet: false
|
||||
directory: '~/.libbitcoind-example',
|
||||
testnet: false,
|
||||
rpc: false
|
||||
});
|
||||
|
||||
bitcoind.on('block', function(block) {
|
||||
console.log('Found Block:');
|
||||
console.log(block);
|
||||
});
|
||||
|
||||
bitcoind.on('addr', function(addr) {
|
||||
console.log('Found more peers to connect to:');
|
||||
console.log(addr);
|
||||
});
|
||||
|
||||
bitcoind.on('open', function() {
|
||||
console.log(bitcoind.wallet.listAccounts());
|
||||
console.log('Your Wallet:');
|
||||
console.log(bitcoind.wallet.getAccounts());
|
||||
});
|
||||
...
|
||||
|
||||
bitcoind.start();
|
||||
```
|
||||
|
||||
``` bash
|
||||
$ node ./my-example.js
|
||||
bitcoind.js: status="start_node(): bitcoind opened."
|
||||
{ '': // Account Name - '' is default
|
||||
Your Wallet:
|
||||
{ '':
|
||||
{ balance: 0,
|
||||
addresses:
|
||||
[ { address: '16PvEk4NggaCyfR2keZaP9nPufJvDb2ATZ',
|
||||
@ -152,420 +153,21 @@ bitcoind.js: shut down.
|
||||
**bitcoind.js** is a node.js module which links to libbitcoind.so (bitcoind
|
||||
complied as a shared library).
|
||||
|
||||
|
||||
### C++ API Structs
|
||||
|
||||
#### `async_node_data`
|
||||
|
||||
Where the uv async request data resides.
|
||||
|
||||
``` c
|
||||
struct async_node_data {
|
||||
std::string err_msg;
|
||||
std::string result;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_block_data`
|
||||
|
||||
``` c
|
||||
struct async_block_data {
|
||||
std::string err_msg;
|
||||
std::string hash;
|
||||
CBlock result_block;
|
||||
CBlockIndex* result_blockindex;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_tx_data`
|
||||
|
||||
``` c
|
||||
struct async_tx_data {
|
||||
std::string err_msg;
|
||||
std::string txHash;
|
||||
std::string blockHash;
|
||||
CTransaction ctx;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_poll_blocks_data`
|
||||
|
||||
``` c
|
||||
struct async_poll_blocks_data {
|
||||
std::string err_msg;
|
||||
poll_blocks_list *head;
|
||||
Persistent<Array> result_array;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `poll_blocks_list`
|
||||
|
||||
A singly linked list containing any polled CBlocks and CBlockIndexes.
|
||||
Contained by `async_poll_blocks_data` struct.
|
||||
|
||||
``` c
|
||||
typedef struct _poll_blocks_list {
|
||||
CBlock cblock;
|
||||
CBlockIndex *cblock_index;
|
||||
struct _poll_blocks_list *next;
|
||||
} poll_blocks_list;
|
||||
```
|
||||
|
||||
#### `async_poll_mempool_data`
|
||||
|
||||
``` c
|
||||
struct async_poll_mempool_data {
|
||||
std::string err_msg;
|
||||
Persistent<Array> result_array;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_broadcast_tx_data`
|
||||
|
||||
``` c
|
||||
struct async_broadcast_tx_data {
|
||||
std::string err_msg;
|
||||
Persistent<Object> jstx;
|
||||
CTransaction ctx;
|
||||
std::string tx_hash;
|
||||
bool override_fees;
|
||||
bool own_only;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_wallet_sendto_data`
|
||||
|
||||
``` c
|
||||
struct async_wallet_sendto_data {
|
||||
std::string err_msg;
|
||||
std::string tx_hash;
|
||||
std::string address;
|
||||
int64_t nAmount;
|
||||
CWalletTx wtx;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_wallet_sendfrom_data`
|
||||
|
||||
``` c
|
||||
struct async_wallet_sendfrom_data {
|
||||
std::string err_msg;
|
||||
std::string tx_hash;
|
||||
std::string address;
|
||||
int64_t nAmount;
|
||||
int nMinDepth;
|
||||
CWalletTx wtx;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
#### `async_import_key_data`
|
||||
|
||||
``` c
|
||||
struct async_import_key_data {
|
||||
std::string err_msg;
|
||||
bool fRescan;
|
||||
Persistent<Function> callback;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
### C++ API Functions
|
||||
|
||||
#### `StartBitcoind()`
|
||||
|
||||
- `bitcoind.start(callback)`
|
||||
- Start the bitcoind node with AppInit2() on a separate thread.
|
||||
|
||||
#### `async_start_node()`
|
||||
|
||||
- Call start_node() and start all our boost threads.
|
||||
|
||||
#### `async_start_node_after()`
|
||||
|
||||
- Execute our callback.
|
||||
|
||||
#### `start_node(void)`
|
||||
|
||||
- Start AppInit2() on a separate thread, wait for
|
||||
pwalletMain instantiation (and signal() calls).
|
||||
Unfortunately, we need to wait for the initialization
|
||||
to unhook the signal handlers so we can use them
|
||||
from node.js in javascript.
|
||||
|
||||
#### `StopBitcoind()`
|
||||
|
||||
- bitcoind.stop(callback)
|
||||
|
||||
#### `async_stop_node()`
|
||||
|
||||
- Call StartShutdown() to join the boost threads, which will call Shutdown()
|
||||
and set shutdownComplete to true to notify the main node.js thread.
|
||||
|
||||
#### `async_stop_node_after()`
|
||||
|
||||
- Execute our callback.
|
||||
|
||||
#### `IsStopping()`
|
||||
|
||||
- `bitcoind.stopping()`
|
||||
- Check whether bitcoind is in the process of shutting down. This is polled
|
||||
from javascript.
|
||||
|
||||
#### `IsStopped()`
|
||||
|
||||
- `bitcoind.stopped()`
|
||||
- Check whether bitcoind has shutdown completely. This will be polled by
|
||||
javascript to check whether the libuv event loop is safe to stop.
|
||||
|
||||
#### `GetBlock()`
|
||||
|
||||
- `bitcoind.getBlock(blockHash, callback)`
|
||||
- Read any block from disk asynchronously.
|
||||
|
||||
#### `GetTx()`
|
||||
|
||||
- `bitcoind.getTx(txHash, [blockHash], callback)`
|
||||
- Read any transaction from disk asynchronously.
|
||||
|
||||
#### `PollBlocks()`
|
||||
|
||||
- `bitcoind.pollBlocks(callback)`
|
||||
- Poll for new blocks on the chain. This is necessary since we have no way of
|
||||
hooking in to AcceptBlock(). Instead, we constant check for new blocks using
|
||||
a SetTimeout() within node.js.
|
||||
- Creating a linked list of all blocks within the work function is necessary
|
||||
due to doing v8 things within the libuv thread pool will cause a segfault.
|
||||
Since this reads full blocks, obviously it will poll for transactions which
|
||||
have already been included in blocks as well.
|
||||
|
||||
#### `PollMempool()`
|
||||
|
||||
- `bitcoind.pollMempool(callback)`
|
||||
- This will poll for any transactions in the mempool. i.e. Transactions which
|
||||
have not been included in blocks yet. This is not technically necessary to
|
||||
be done asynchronously since there are no real blocking calls done here, but
|
||||
we will leave the async function here as a placeholder in case we're wrong.
|
||||
|
||||
#### `BroadcastTx()`
|
||||
- `bitcoind.broadcastTx(tx, override_fees, own_only, callback)`
|
||||
- Broadcast a raw transaction. This can be used to relay transaction received
|
||||
or to broadcast one's own transaction.
|
||||
|
||||
#### `VerifyBlock()`
|
||||
- `bitcoindjs.verifyBlock(block)`
|
||||
- This will verify the authenticity of a block (merkleRoot, etc)
|
||||
using the internal bitcoind functions.
|
||||
|
||||
#### `VerifyTransaction()`
|
||||
|
||||
- `bitcoindjs.verifyTransaction(tx)`
|
||||
- This will verify a transaction, ensuring it is signed properly using the
|
||||
internal bitcoind functions.
|
||||
|
||||
#### `FillTransaction()`
|
||||
|
||||
- `bitcoindjs.fillTransaction(tx, options)`
|
||||
- This will fill a javascript transaction object with the proper available
|
||||
unpsent outputs as inputs and sign them using internal bitcoind functions.
|
||||
|
||||
#### `GetBlockHex()`
|
||||
- `bitcoindjs.getBlockHex(callback)`
|
||||
- This will return the hex value as well as hash of a javascript block object
|
||||
(after being converted to a CBlock).
|
||||
|
||||
#### `GetTxHex()`
|
||||
|
||||
- `bitcoindjs.getTxHex(tx)`
|
||||
- This will return the hex value and hash for any tx, converting a js tx
|
||||
object to a CTransaction.
|
||||
|
||||
#### `BlockFromHex()`
|
||||
|
||||
- `bitcoindjs.blockFromHex(hex)`
|
||||
- Create a javascript block from a hex string.
|
||||
|
||||
#### `TxFromHex()`
|
||||
|
||||
- `bitcoindjs.txFromHex(hex)`
|
||||
- Create a javascript tx from a hex string.
|
||||
|
||||
#### `WalletNewAddress()`
|
||||
|
||||
- `bitcoindjs.walletNewAddress(options)`
|
||||
- Create a new address in the global pwalletMain.
|
||||
|
||||
#### `GetAccountAddress(strAccount, bForceNew)`
|
||||
|
||||
- `CBitcoinAddress GetAccountAddress(std::string strAccount, bool bForceNew)`
|
||||
- NOTE: This function was ripped out of the bitcoin core source. It needed to
|
||||
be modified to fit v8's error handling.
|
||||
|
||||
#### `WalletGetAccountAddress()`
|
||||
|
||||
- `bitcoindjs.walletGetAccountAddress(options)`
|
||||
- Return the address tied to a specific account name.
|
||||
|
||||
#### `WalletSetAccount()`
|
||||
|
||||
- `bitcoindjs.walletSetAccount(options)`
|
||||
- Return a new address if the account does not exist, or tie an account to an
|
||||
address.
|
||||
|
||||
#### `WalletGetAccount()`
|
||||
|
||||
- `bitcoindjs.walletGetAccount(options)`
|
||||
- Get an account name based on address.
|
||||
|
||||
#### `WalletSendTo()`
|
||||
|
||||
- `bitcoindjs.walletSendTo(options)`
|
||||
- Send bitcoin to an address, automatically creating the transaction based on
|
||||
availing unspent outputs.
|
||||
|
||||
#### `WalletSignMessage()`
|
||||
|
||||
- `bitcoindjs.walletSignMessage(options)`
|
||||
- Sign any piece of text using a private key tied to an address.
|
||||
|
||||
#### `WalletVerifyMessage()`
|
||||
|
||||
- `bitcoindjs.walletVerifyMessage(options)`
|
||||
- Verify a signed message using any address' public key.
|
||||
|
||||
#### `WalletCreateMultiSigAddress()`
|
||||
|
||||
- `bitcoindjs.walletCreateMultiSigAddress(options)`
|
||||
- Create a multisig address for the global wallet.
|
||||
|
||||
#### `WalletGetBalance()`
|
||||
|
||||
- `bitcoindjs.walletGetBalance(options)`
|
||||
- Get total balance of global wallet in satoshies in a javascript Number (up
|
||||
to 64 bits, only 32 if bitwise ops or floating point are used unfortunately.
|
||||
Obviously floating point is not necessary for satoshies).
|
||||
|
||||
#### `WalletGetUnconfirmedBalance()`
|
||||
|
||||
- `bitcoindjs.walletGetUnconfirmedBalance(options)`
|
||||
- Returns the unconfirmed balance in satoshies (including the transactions
|
||||
that have not yet been included in any block).
|
||||
|
||||
#### `WalletSendFrom()`
|
||||
|
||||
- `bitcoindjs.walletSendFrom(options)`
|
||||
- Send bitcoin to a particular address from a particular owned account name.
|
||||
This once again automatically creates and signs a transaction based on any
|
||||
unspent outputs available.
|
||||
|
||||
#### `WalletListTransactions()`
|
||||
|
||||
- `bitcoindjs.walletListTransactions(options)`
|
||||
- List all transactions pertaining to any owned addreses. NOT YET IMPLEMENTED>
|
||||
|
||||
#### `WalletListAccounts()`
|
||||
|
||||
- `bitcoindjs.walletListAccounts(options)`
|
||||
- This will list all accounts, addresses, balanced, private keys, public keys,
|
||||
and whether these keys are in compressed format. TODO: Only output private
|
||||
keys if wallet is decrypted.
|
||||
|
||||
#### `WalletGetTransaction()`
|
||||
|
||||
- `bitcoindjs.walletGetTransaction(options)`
|
||||
- Get any transaction pertaining to any owned addresses. NOT YET IMPLEMENTED.
|
||||
|
||||
#### `WalletBackup()`
|
||||
|
||||
- `bitcoindjs.walletBackup(options)`
|
||||
- Backup the bdb wallet.dat to a particular location on filesystem.
|
||||
|
||||
#### `WalletPassphrase()`
|
||||
|
||||
- `bitcoindjs.walletPassphrase(options)`
|
||||
- Unlock wallet if encrypted already.
|
||||
|
||||
#### `WalletPassphraseChange()`
|
||||
|
||||
- `bitcoindjs.walletPassphraseChange(options)`
|
||||
- Change the current passphrase for the encrypted wallet.
|
||||
|
||||
#### `WalletLock()`
|
||||
|
||||
- `bitcoindjs.walletLock(options)`
|
||||
- Forget the encrypted wallet passphrase and lock the wallet once again.
|
||||
|
||||
#### `WalletEncrypt()`
|
||||
|
||||
- `bitcoindjs.walletEncrypt(options)`
|
||||
- Encrypt the global wallet with a particular passphrase. Requires restarted
|
||||
because Berkeley DB is bad.
|
||||
|
||||
#### `WalletSetTxFee()`
|
||||
|
||||
- `bitcoindjs.walletSetTxFee(options)`
|
||||
- Set default global wallet transaction fee internally.
|
||||
|
||||
#### `WalletImportKey()`
|
||||
|
||||
- `bitcoindjs.walletImportKey(options)`
|
||||
- Import private key into global wallet using standard compressed bitcoind
|
||||
format.
|
||||
|
||||
#### Conversions
|
||||
|
||||
- `cblock_to_jsblock(cblock, cblock_index, jsblock)`
|
||||
- `ctx_to_jstx(ctx, block_hash, jstx)`
|
||||
- `jsblock_to_cblock(jsblock, cblock)`
|
||||
- `jstx_to_ctx(jstx, ctx)`
|
||||
|
||||
These functions, only callable from C++, are used to convert javascript blocks
|
||||
and tx objects to bitcoin block and tx objects (CBlocks and CTransactions), and
|
||||
vice versa.
|
||||
|
||||
NOTE: For whatever reason when converting a jstx to a CTransaction via setting
|
||||
CTransaction properties, the binary output of a jstx is not the same as what
|
||||
went in. It is unknow why this occurs. For now we are are using a workaround by
|
||||
carrying the original hex value on the object which is changed when the tx is
|
||||
changed.
|
||||
|
||||
#### `Init()`
|
||||
|
||||
Initialize the singleton object known as bitcoindjs. Required by every node.js
|
||||
C++ module.
|
||||
|
||||
|
||||
### Javascript API
|
||||
|
||||
#### Bitcoin Object/Class
|
||||
|
||||
Bitcoind in javascript. Right now, only one object can be instantiated.
|
||||
|
||||
##### `Bitcoin::start(callback)`
|
||||
##### `Bitcoin::start([options], [callback])`
|
||||
|
||||
Start the javascript bitcoin node.
|
||||
|
||||
##### `Bitcoin::_pollBlocks()`
|
||||
|
||||
Internally poll for blocks using setTimeout. Private.
|
||||
|
||||
##### `Bitcoin::_pollMempool()`
|
||||
|
||||
Internally poll for mempool txs that have not been included in blocks yet.
|
||||
Private.
|
||||
|
||||
##### `Bitcoin::getBlock(blockHash, callback)`
|
||||
|
||||
Get any block asynchronously by reading it from disk.
|
||||
|
||||
##### `Bitcoin::getTx(txHash, blockHash, callback)`
|
||||
##### `Bitcoin::getTransaction(txid, blockhash, callback)`
|
||||
|
||||
Get any tx asynchronously by reading it from disk.
|
||||
|
||||
|
||||
283
example/index.js
Executable file
283
example/index.js
Executable file
@ -0,0 +1,283 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* bitcoind.js example
|
||||
*/
|
||||
|
||||
process.title = 'bitcoind.js';
|
||||
|
||||
var util = require('util');
|
||||
var fs = require('fs');
|
||||
var argv = require('optimist').argv;
|
||||
var rimraf = require('rimraf');
|
||||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
* bitcoind
|
||||
*/
|
||||
|
||||
if (fs.existsSync(process.env.HOME + '/.libbitcoind-example')) {
|
||||
rimraf.sync(process.env.HOME + '/.libbitcoind-example');
|
||||
}
|
||||
|
||||
var bitcoind = require('../')({
|
||||
directory: '~/.libbitcoind-example'
|
||||
});
|
||||
|
||||
var genesisBlock = '0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f';
|
||||
var genesisTx = '0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
|
||||
|
||||
var testBlock = ''
|
||||
+ '0100000090f0a9f110702f808219ebea1173056042a714bad51b916cb6800000000000'
|
||||
+ '005275289558f51c9966699404ae2294730c3c9f9bda53523ce50e9b95e558da2fdb26'
|
||||
+ '1b4d4c86041b1ab1bf9309010000000100000000000000000000000000000000000000'
|
||||
+ '00000000000000000000000000ffffffff07044c86041b0146ffffffff0100f2052a01'
|
||||
+ '000000434104e18f7afbe4721580e81e8414fc8c24d7cfacf254bb5c7b949450c3e997'
|
||||
+ 'c2dc1242487a8169507b631eb3771f2b425483fb13102c4eb5d858eef260fe70fbfae0'
|
||||
+ 'ac00000000010000000196608ccbafa16abada902780da4dc35dafd7af05fa0da08cf8'
|
||||
+ '33575f8cf9e836000000004a493046022100dab24889213caf43ae6adc41cf1c9396c0'
|
||||
+ '8240c199f5225acf45416330fd7dbd022100fe37900e0644bf574493a07fc5edba06db'
|
||||
+ 'c07c311b947520c2d514bc5725dcb401ffffffff0100f2052a010000001976a914f15d'
|
||||
+ '1921f52e4007b146dfa60f369ed2fc393ce288ac000000000100000001fb766c128845'
|
||||
+ '8c2bafcfec81e48b24d98ec706de6b8af7c4e3c29419bfacb56d000000008c49304602'
|
||||
+ '2100f268ba165ce0ad2e6d93f089cfcd3785de5c963bb5ea6b8c1b23f1ce3e517b9f02'
|
||||
+ '2100da7c0f21adc6c401887f2bfd1922f11d76159cbc597fbd756a23dcbb00f4d72901'
|
||||
+ '41042b4e8625a96127826915a5b109852636ad0da753c9e1d5606a50480cd0c40f1f8b'
|
||||
+ '8d898235e571fe9357d9ec842bc4bba1827daaf4de06d71844d0057707966affffffff'
|
||||
+ '0280969800000000001976a9146963907531db72d0ed1a0cfb471ccb63923446f388ac'
|
||||
+ '80d6e34c000000001976a914f0688ba1c0d1ce182c7af6741e02658c7d4dfcd388ac00'
|
||||
+ '0000000100000002c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031'
|
||||
+ '895b52f2ff010000008b483045022100f7edfd4b0aac404e5bab4fd3889e0c6c41aa8d'
|
||||
+ '0e6fa122316f68eddd0a65013902205b09cc8b2d56e1cd1f7f2fafd60a129ed94504c4'
|
||||
+ 'ac7bdc67b56fe67512658b3e014104732012cb962afa90d31b25d8fb0e32c94e513ab7'
|
||||
+ 'a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f49'
|
||||
+ '08b18368d6fc2d68ecffffffffca5065ff9617cbcba45eb23726df6498a9b9cafed4f5'
|
||||
+ '4cbab9d227b0035ddefb000000008a473044022068010362a13c7f9919fa832b2dee4e'
|
||||
+ '788f61f6f5d344a7c2a0da6ae740605658022006d1af525b9a14a35c003b78b72bd597'
|
||||
+ '38cd676f845d1ff3fc25049e01003614014104732012cb962afa90d31b25d8fb0e32c9'
|
||||
+ '4e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097'
|
||||
+ 'b7d04f4908b18368d6fc2d68ecffffffff01001ec4110200000043410469ab4181eceb'
|
||||
+ '28985b9b4e895c13fa5e68d85761b7eee311db5addef76fa8621865134a221bd01f28e'
|
||||
+ 'c9999ee3e021e60766e9d1f3458c115fb28650605f11c9ac000000000100000001cdaf'
|
||||
+ '2f758e91c514655e2dc50633d1e4c84989f8aa90a0dbc883f0d23ed5c2fa010000008b'
|
||||
+ '48304502207ab51be6f12a1962ba0aaaf24a20e0b69b27a94fac5adf45aa7d2d18ffd9'
|
||||
+ '236102210086ae728b370e5329eead9accd880d0cb070aea0c96255fae6c4f1ddcce1f'
|
||||
+ 'd56e014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f5'
|
||||
+ '5c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ff'
|
||||
+ 'ffffff02404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5'
|
||||
+ 'c388ac002d3101000000001976a9141befba0cdc1ad56529371864d9f6cb042faa06b5'
|
||||
+ '88ac000000000100000001b4a47603e71b61bc3326efd90111bf02d2f549b067f4c4a8'
|
||||
+ 'fa183b57a0f800cb010000008a4730440220177c37f9a505c3f1a1f0ce2da777c339bd'
|
||||
+ '8339ffa02c7cb41f0a5804f473c9230220585b25a2ee80eb59292e52b987dad92acb0c'
|
||||
+ '64eced92ed9ee105ad153cdb12d001410443bd44f683467e549dae7d20d1d79cbdb6df'
|
||||
+ '985c6e9c029c8d0c6cb46cc1a4d3cf7923c5021b27f7a0b562ada113bc85d5fda5a1b4'
|
||||
+ '1e87fe6e8802817cf69996ffffffff0280651406000000001976a9145505614859643a'
|
||||
+ 'b7b547cd7f1f5e7e2a12322d3788ac00aa0271000000001976a914ea4720a7a52fc166'
|
||||
+ 'c55ff2298e07baf70ae67e1b88ac00000000010000000586c62cd602d219bb60edb14a'
|
||||
+ '3e204de0705176f9022fe49a538054fb14abb49e010000008c493046022100f2bc2aba'
|
||||
+ '2534becbdf062eb993853a42bbbc282083d0daf9b4b585bd401aa8c9022100b1d7fd7e'
|
||||
+ 'e0b95600db8535bbf331b19eed8d961f7a8e54159c53675d5f69df8c014104462e76fd'
|
||||
+ '4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b'
|
||||
+ '3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff03ad0e58ccda'
|
||||
+ 'c3df9dc28a218bcf6f1997b0a93306faaa4b3a28ae83447b2179010000008b48304502'
|
||||
+ '2100be12b2937179da88599e27bb31c3525097a07cdb52422d165b3ca2f2020ffcf702'
|
||||
+ '200971b51f853a53d644ebae9ec8f3512e442b1bcb6c315a5b491d119d10624c830141'
|
||||
+ '04462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4'
|
||||
+ 'b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff2a'
|
||||
+ 'cfcab629bbc8685792603762c921580030ba144af553d271716a95089e107b01000000'
|
||||
+ '8b483045022100fa579a840ac258871365dd48cd7552f96c8eea69bd00d84f05b283a0'
|
||||
+ 'dab311e102207e3c0ee9234814cfbb1b659b83671618f45abc1326b9edcc77d552a4f2'
|
||||
+ 'a805c0014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0'
|
||||
+ 'f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4'
|
||||
+ 'ffffffffdcdc6023bbc9944a658ddc588e61eacb737ddf0a3cd24f113b5a8634c517fc'
|
||||
+ 'd2000000008b4830450221008d6df731df5d32267954bd7d2dda2302b74c6c2a6aa5c0'
|
||||
+ 'ca64ecbabc1af03c75022010e55c571d65da7701ae2da1956c442df81bbf076cdbac25'
|
||||
+ '133f99d98a9ed34c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d7'
|
||||
+ '89904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8'
|
||||
+ 'ebbb12dcd4ffffffffe15557cd5ce258f479dfd6dc6514edf6d7ed5b21fcfa4a038fd6'
|
||||
+ '9f06b83ac76e010000008b483045022023b3e0ab071eb11de2eb1cc3a67261b866f86b'
|
||||
+ 'f6867d4558165f7c8c8aca2d86022100dc6e1f53a91de3efe8f63512850811f26284b6'
|
||||
+ '2f850c70ca73ed5de8771fb451014104462e76fd4067b3a0aa42070082dcb0bf2f388b'
|
||||
+ '6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15'
|
||||
+ '312ef1c0e8ebbb12dcd4ffffffff01404b4c00000000001976a9142b6ba7c9d796b75e'
|
||||
+ 'ef7942fc9288edd37c32f5c388ac00000000010000000166d7577163c932b4f9690ca6'
|
||||
+ 'a80b6e4eb001f0a2fa9023df5595602aae96ed8d000000008a4730440220262b425463'
|
||||
+ '02dfb654a229cefc86432b89628ff259dc87edd1154535b16a67e102207b4634c020a9'
|
||||
+ '7c3e7bbd0d4d19da6aa2269ad9dded4026e896b213d73ca4b63f014104979b82d02226'
|
||||
+ 'b3a4597523845754d44f13639e3bf2df5e82c6aab2bdc79687368b01b1ab8b19875ae3'
|
||||
+ 'c90d661a3d0a33161dab29934edeb36aa01976be3baf8affffffff02404b4c00000000'
|
||||
+ '001976a9144854e695a02af0aeacb823ccbc272134561e0a1688ac40420f0000000000'
|
||||
+ '1976a914abee93376d6b37b5c2940655a6fcaf1c8e74237988ac000000000100000001'
|
||||
+ '4e3f8ef2e91349a9059cb4f01e54ab2597c1387161d3da89919f7ea6acdbb371010000'
|
||||
+ '008c49304602210081f3183471a5ca22307c0800226f3ef9c353069e0773ac76bb5806'
|
||||
+ '54d56aa523022100d4c56465bdc069060846f4fbf2f6b20520b2a80b08b168b31e66dd'
|
||||
+ 'b9c694e240014104976c79848e18251612f8940875b2b08d06e6dc73b9840e8860c066'
|
||||
+ 'b7e87432c477e9a59a453e71e6d76d5fe34058b800a098fc1740ce3012e8fc8a00c96a'
|
||||
+ 'f966ffffffff02c0e1e400000000001976a9144134e75a6fcb6042034aab5e18570cf1'
|
||||
+ 'f844f54788ac404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c'
|
||||
+ '32f5c388ac00000000';
|
||||
|
||||
var testTx = ''
|
||||
+ '01000000010b26e9b7735eb6aabdf358bab62f9816a21ba9ebdb719d5299e88607d722'
|
||||
+ 'c190000000008b4830450220070aca44506c5cef3a16ed519d7c3c39f8aab192c4e1c9'
|
||||
+ '0d065f37b8a4af6141022100a8e160b856c2d43d27d8fba71e5aef6405b8643ac4cb7c'
|
||||
+ 'b3c462aced7f14711a0141046d11fee51b0e60666d5049a9101a72741df480b96ee264'
|
||||
+ '88a4d3466b95c9a40ac5eeef87e10a5cd336c19a84565f80fa6c547957b7700ff4dfbd'
|
||||
+ 'efe76036c339ffffffff021bff3d11000000001976a91404943fdd508053c75000106d'
|
||||
+ '3bc6e2754dbcff1988ac2f15de00000000001976a914a266436d2965547608b9e15d90'
|
||||
+ '32a7b9d64fa43188ac00000000';
|
||||
|
||||
bitcoind.on('error', function(err) {
|
||||
bitcoind.log('error="%s"', err.message);
|
||||
});
|
||||
|
||||
bitcoind.on('open', function(status) {
|
||||
bitcoind.log('status="%s"', status);
|
||||
|
||||
if (argv.list) {
|
||||
return bitcoind.log(bitcoind.wallet.listAccounts());
|
||||
}
|
||||
|
||||
if (argv.blocks) {
|
||||
return getBlocks(bitcoind);
|
||||
}
|
||||
|
||||
function assertHex(obj) {
|
||||
// Hash
|
||||
if (obj.txid) {
|
||||
assert.equal(obj.hash, obj.getHash('hex'));
|
||||
} else {
|
||||
assert.equal(obj.hash, obj.getHash('hex'));
|
||||
}
|
||||
// Hex
|
||||
if (obj.txid) {
|
||||
assert.equal(obj.hex, obj.toHex());
|
||||
} else {
|
||||
assert.equal(obj.hex, obj.toHex());
|
||||
}
|
||||
}
|
||||
|
||||
if (argv['on-block']) {
|
||||
return bitcoind.on('block', function callee(block) {
|
||||
if (block.tx.length === 1) return;
|
||||
bitcoind.log('Found Block:');
|
||||
bitcoind.log(block);
|
||||
return assertHex(block);
|
||||
});
|
||||
}
|
||||
|
||||
if (argv['on-tx']) {
|
||||
bitcoind.on('tx', function(tx) {
|
||||
bitcoind.log('Found TX:');
|
||||
bitcoind.log(tx);
|
||||
return assertHex(tx);
|
||||
});
|
||||
bitcoind.on('mptx', function(mptx) {
|
||||
bitcoind.log('Found mempool TX:');
|
||||
bitcoind.log(mptx);
|
||||
return assertHex(mptx);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv.broadcast) {
|
||||
// Help propagate transactions
|
||||
return bitcoind.once('tx', function(tx) {
|
||||
bitcoind.log('Broadcasting TX...');
|
||||
return tx.broadcast(function(err, hash, tx) {
|
||||
if (err) throw err;
|
||||
bitcoind.log('TX Hash: %s', hash);
|
||||
return bitcoind.log(tx);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Test fromHex:
|
||||
if (argv['from-hex']) {
|
||||
var block = bitcoind.block(testBlock);
|
||||
assert.equal(block.hash, '0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af');
|
||||
assert.equal(block.merkleroot, '2fda58e5959b0ee53c5253da9b9f3c0c739422ae04946966991cf55895287552');
|
||||
bitcoind.log('Block:');
|
||||
bitcoind.log(block);
|
||||
var tx = bitcoind.tx(testTx);
|
||||
assert.equal(tx.txid, 'b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b');
|
||||
bitcoind.log('Transaction:');
|
||||
bitcoind.log(tx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test all digest packets:
|
||||
if (argv['packets']) {
|
||||
bitcoind.on('digest', function(packet) {
|
||||
return bitcoind.log(packet);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
argv['on-block'] = true;
|
||||
setTimeout(function() {
|
||||
bitcoind.on('block', function callee(block) {
|
||||
if (!argv['on-block']) {
|
||||
return bitcoind.removeListener('block', callee);
|
||||
}
|
||||
bitcoind.log('Found Block:');
|
||||
bitcoind.log(block);
|
||||
return assertHex(block);
|
||||
});
|
||||
|
||||
bitcoind.once('block', function(block) {
|
||||
setTimeout(function() {
|
||||
argv['on-block'] = false;
|
||||
|
||||
bitcoind.log(bitcoind.getInfo());
|
||||
bitcoind.log(bitcoind.getPeerInfo());
|
||||
bitcoind.log(bitcoind.wallet.listAccounts());
|
||||
bitcoind.log(bitcoind.wallet.getRecipients());
|
||||
|
||||
bitcoind.once('version', function(version) {
|
||||
bitcoind.log('VERSION packet:');
|
||||
bitcoind.log(version);
|
||||
});
|
||||
|
||||
bitcoind.once('addr', function(addr) {
|
||||
bitcoind.log('ADDR packet:');
|
||||
bitcoind.log(addr);
|
||||
});
|
||||
}, 8000);
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
return bitcoind.log(bitcoind.wallet.listAccounts());
|
||||
});
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function getBlocks(bitcoind) {
|
||||
return setTimeout(function() {
|
||||
return (function next(hash) {
|
||||
return bitcoind.getBlock(hash, function(err, block) {
|
||||
if (err) return bitcoind.log(err.message);
|
||||
|
||||
bitcoind.log(block);
|
||||
|
||||
if (argv['get-tx'] && block.tx.length && block.tx[0].txid) {
|
||||
var txid = block.tx[0].txid;
|
||||
// XXX Dies with a segfault
|
||||
// bitcoind.getTx(txid, hash, function(err, tx) {
|
||||
bitcoind.getTx(txid, function(err, tx) {
|
||||
if (err) return bitcoind.log(err.message);
|
||||
bitcoind.log('TX -----------------------------------------------------');
|
||||
bitcoind.log(tx);
|
||||
bitcoind.log('/TX ----------------------------------------------------');
|
||||
});
|
||||
}
|
||||
|
||||
if (block.nextblockhash) {
|
||||
setTimeout(next.bind(null, block.nextblockhash), 500);
|
||||
}
|
||||
});
|
||||
})(genesisBlock);
|
||||
}, 1000);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user