fix and improve SendTx example
This commit is contained in:
parent
84ec7bae4c
commit
fc1dcbd9d0
143
README.md
143
README.md
|
@ -62,42 +62,43 @@ addrs.forEach(function(addr) {
|
|||
For this example you need a running bitcoind instance with RPC enabled.
|
||||
|
||||
```js
|
||||
var bitcore = require('bitcore');
|
||||
var networks = bitcore.networks;
|
||||
var Peer = bitcore.Peer;
|
||||
var PeerManager = require('soop').load('../PeerManager', {
|
||||
network: networks.testnet
|
||||
});
|
||||
var bitcore = require('../bitcore');
|
||||
var Peer = bitcore.Peer;
|
||||
var PeerManager = bitcore.PeerManager;
|
||||
|
||||
var handleBlock = function(info) {
|
||||
var handleBlock = function(info) {
|
||||
console.log('** Block Received **');
|
||||
console.log(info.message);
|
||||
};
|
||||
};
|
||||
|
||||
var handleTx = function(info) {
|
||||
var handleTx = function(info) {
|
||||
var tx = info.message.tx.getStandardizedObject();
|
||||
|
||||
console.log('** TX Received **');
|
||||
console.log(tx);
|
||||
};
|
||||
};
|
||||
|
||||
var handleInv = function(info) {
|
||||
var handleInv = function(info) {
|
||||
console.log('** Inv **');
|
||||
console.log(info.message);
|
||||
|
||||
var invs = info.message.invs;
|
||||
info.conn.sendGetData(invs);
|
||||
};
|
||||
};
|
||||
|
||||
var peerman = new PeerManager();
|
||||
var peerman = new PeerManager({
|
||||
network: 'testnet'
|
||||
});
|
||||
|
||||
peerman.addPeer(new Peer('127.0.0.1', 18333));
|
||||
peerman.addPeer(new Peer('127.0.0.1', 18333));
|
||||
|
||||
peerman.on('connection', function(conn) {
|
||||
peerman.on('connection', function(conn) {
|
||||
conn.on('inv', handleInv);
|
||||
conn.on('block', handleBlock);
|
||||
conn.on('tx', handleTx);
|
||||
});
|
||||
});
|
||||
|
||||
peerman.start();
|
||||
peerman.start();
|
||||
```
|
||||
|
||||
PeerManager will emit the following events: 'version', 'verack', 'addr', 'getaddr', 'error' 'disconnect'; and will relay events like: 'tx', 'block', 'inv'. Please see [PeerManager.js](PeerManager.js), [Peer.js](Peer.js) and [Connection.js](Connection.js)
|
||||
|
@ -140,51 +141,58 @@ by the transaction size. Documentation on the parameters of `TransactionBuilder`
|
|||
can be found on the source file.
|
||||
|
||||
```js
|
||||
var bitcore = require('bitcore');
|
||||
var networks = bitcore.networks;
|
||||
var Peer = bitcore.Peer;
|
||||
var TransactionBuilder = bitcore.TransactionBuilder;
|
||||
var PeerManager = require('soop').load('../PeerManager', {
|
||||
network: networks.testnet
|
||||
});
|
||||
var bitcore = require('bitcore');
|
||||
var Peer = bitcore.Peer;
|
||||
var TransactionBuilder = bitcore.TransactionBuilder;
|
||||
var PeerManager = bitcore.PeerManager;
|
||||
|
||||
// Unspent transactions can be found via the insight.bitcore.io or blockchain.info APIs
|
||||
var unspent = [
|
||||
{
|
||||
"address": "n4g2TFaQo8UgedwpkYdcQFF6xE2Ei9Czvy",
|
||||
"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
|
||||
"scriptPubKey": "76a914fe021bac469a5c49915b2a8ffa7390a9ce5580f988ac",
|
||||
"vout": 1,
|
||||
"amount": 1.0101,
|
||||
"confirmations":7
|
||||
},
|
||||
{
|
||||
"address": "mhNCT9TwZAGF1tLPpZdqfkTmtBkY282YDW",
|
||||
"txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc2",
|
||||
"scriptPubKey": "76a9141448534cb1a1ec44665b0eb2326e570814afe3f188ac",
|
||||
"vout": 0,
|
||||
"confirmations": 1,
|
||||
"amount": 10
|
||||
// Unspent transactions can be found via the insight.bitcore.io or blockchain.info APIs
|
||||
var unspent = [{
|
||||
'txid': '707108b5ba4f78dc951df4647a03365bf36432ea57fb641676045c5044daaea7',
|
||||
'vout': 0,
|
||||
'address': 'n3QDC7DzsMmN4mcyp3k7XGPX7zFXXHG387',
|
||||
'scriptPubKey': '76a914f00c4a92ee2314ab08ac0283dc8d07d9bf2be32388ac',
|
||||
'amount': 0.12345600,
|
||||
'confirmations': 43537
|
||||
}, {
|
||||
'txid': '87a158d32833cb555aea27b6a21af569ccaeb8f9b19691e05f1e6c2b3440bdb3',
|
||||
'vout': 1,
|
||||
'address': 'mxdrp9s4mVxS9X4RBYiLe99v59V81XA5C3',
|
||||
'scriptPubKey': '76a914bbc87986da6b17c7876db4efacf59a95e14f6cf588ac',
|
||||
'amount': 0.05749800,
|
||||
'confirmations': 43536
|
||||
}
|
||||
];
|
||||
|
||||
// Private keys in WIF format (see TransactionBuilder.js for other options)
|
||||
var keys = [
|
||||
"cSq7yo4fvsbMyWVN945VUGUWMaSazZPWqBVJZyoGsHmNq6W4HVBV",
|
||||
"cPa87VgwZfowGZYaEenoQeJgRfKW6PhZ1R65EHTkN1K19cSvc92G",
|
||||
"cPQ9DSbBRLva9av5nqeF5AGrh3dsdW8p2E5jS4P8bDWZAoQTeeKB"
|
||||
];
|
||||
];
|
||||
|
||||
var peerman = new PeerManager();
|
||||
peerman.addPeer(new Peer('127.0.0.1', 18333));
|
||||
// Private keys in WIF format (see TransactionBuilder.js for other options)
|
||||
var keys = [
|
||||
'cQA75LXhV5JkMT8wkkqjR87SnHK4doh3c21p7PAd5tp8tc1tRBAY',
|
||||
'cRz85dz9AiDieRpEwoucfXXQa1jdHHghcv6YnnVVGZ3MQyR1X4u2',
|
||||
'cSq7yo4fvsbMyWVN945VUGUWMaSazZPWqBVJZyoGsHmNq6W4HVBV',
|
||||
'cPa87VgwZfowGZYaEenoQeJgRfKW6PhZ1R65EHTkN1K19cSvc92G',
|
||||
'cPQ9DSbBRLva9av5nqeF5AGrh3dsdW8p2E5jS4P8bDWZAoQTeeKB'
|
||||
];
|
||||
|
||||
peerman.on('connect', function() {
|
||||
var peerman = new PeerManager({
|
||||
network: 'testnet'
|
||||
});
|
||||
peerman.addPeer(new Peer('127.0.0.1', 18333));
|
||||
|
||||
peerman.on('connect', function() {
|
||||
var conn = peerman.getActiveConnection();
|
||||
if (conn) {
|
||||
var outs = [{address: toAddress, amount: amt}];
|
||||
var opts = {remainderOut: {address: changeAddressString}};
|
||||
var TransactionBuilder = bitcore.TransactionBuilder;
|
||||
|
||||
// define transaction output
|
||||
var outs = [{
|
||||
address: 'mhNCT9TwZAGF1tLPpZdqfkTmtBkY282YDW',
|
||||
amount: 0.1337
|
||||
}];
|
||||
// set change address
|
||||
var opts = {
|
||||
remainderOut: {
|
||||
address: 'n4g2TFaQo8UgedwpkYdcQFF6xE2Ei9Czvy'
|
||||
}
|
||||
};
|
||||
var tx = new TransactionBuilder(opts)
|
||||
.setUnspent(unspent)
|
||||
.setOutputs(outs)
|
||||
|
@ -209,14 +217,25 @@ peerman.on('connect', function() {
|
|||
*
|
||||
* var selectedUnspent = build.getSelectedUnspent(); // Retrieve selected unspent outputs from the transaction
|
||||
*/
|
||||
conn.sendTx(tx.serialize().toString('hex'));
|
||||
}
|
||||
conn.on('reject', function() {
|
||||
console.log('Transaction Rejected');
|
||||
});
|
||||
});
|
||||
|
||||
peerman.start();
|
||||
var txid = tx.getHash().toString('hex');
|
||||
console.log('Created transaction with txid '+txid);
|
||||
var raw_tx = tx.serialize().toString('hex');
|
||||
console.log('Transaction raw hex dump:');
|
||||
console.log('-------------------------------------');
|
||||
console.log(raw_tx);
|
||||
console.log('-------------------------------------');
|
||||
// finally, send transaction to the bitcoin network
|
||||
conn.sendTx(tx);
|
||||
|
||||
// for now, the network won't respond in any case
|
||||
// (transaction accepted, transaction rejected)
|
||||
// in the future, we may listen to 'reject' message
|
||||
// see https://gist.github.com/gavinandresen/7079034
|
||||
}
|
||||
});
|
||||
|
||||
peerman.start();
|
||||
```
|
||||
|
||||
## Parsing a Script
|
||||
|
|
|
@ -4,67 +4,100 @@ var run = function() {
|
|||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
||||
var bitcore = require('../bitcore');
|
||||
var Peer = bitcore.Peer;
|
||||
var Transaction = bitcore.Transaction;
|
||||
var Address = bitcore.Address;
|
||||
var Script = bitcore.Script;
|
||||
var coinUtil = bitcore.util;
|
||||
var TransactionBuilder = bitcore.TransactionBuilder;
|
||||
var PeerManager = bitcore.PeerManager;
|
||||
|
||||
var createTx = function() {
|
||||
var TXIN = 'd05f35e0bbc495f6dcab03e599c8f5e32a07cdb4bc76964de201d06a2a7d8265';
|
||||
var TXIN_N = 0;
|
||||
var ADDR = 'muHct3YZ9Nd5Pq7uLYYhXRAxeW4EnpcaLz';
|
||||
var VAL = '0.001';
|
||||
// Unspent transactions can be found via the insight.bitcore.io or blockchain.info APIs
|
||||
var unspent = [{
|
||||
'txid': '707108b5ba4f78dc951df4647a03365bf36432ea57fb641676045c5044daaea7',
|
||||
'vout': 0,
|
||||
'address': 'n3QDC7DzsMmN4mcyp3k7XGPX7zFXXHG387',
|
||||
'scriptPubKey': '76a914f00c4a92ee2314ab08ac0283dc8d07d9bf2be32388ac',
|
||||
'amount': 0.12345600,
|
||||
'confirmations': 43537
|
||||
}, {
|
||||
'txid': '87a158d32833cb555aea27b6a21af569ccaeb8f9b19691e05f1e6c2b3440bdb3',
|
||||
'vout': 1,
|
||||
'address': 'mxdrp9s4mVxS9X4RBYiLe99v59V81XA5C3',
|
||||
'scriptPubKey': '76a914bbc87986da6b17c7876db4efacf59a95e14f6cf588ac',
|
||||
'amount': 0.05749800,
|
||||
'confirmations': 43536
|
||||
}
|
||||
|
||||
var txobj = {
|
||||
version: 1,
|
||||
lock_time: 0,
|
||||
ins: [],
|
||||
outs: []
|
||||
};
|
||||
];
|
||||
|
||||
var txin = {
|
||||
s: coinUtil.EMPTY_BUFFER, // Add signature
|
||||
q: 0xffffffff
|
||||
};
|
||||
// Private keys in WIF format (see TransactionBuilder.js for other options)
|
||||
var keys = [
|
||||
'cQA75LXhV5JkMT8wkkqjR87SnHK4doh3c21p7PAd5tp8tc1tRBAY',
|
||||
'cRz85dz9AiDieRpEwoucfXXQa1jdHHghcv6YnnVVGZ3MQyR1X4u2',
|
||||
'cSq7yo4fvsbMyWVN945VUGUWMaSazZPWqBVJZyoGsHmNq6W4HVBV',
|
||||
'cPa87VgwZfowGZYaEenoQeJgRfKW6PhZ1R65EHTkN1K19cSvc92G',
|
||||
'cPQ9DSbBRLva9av5nqeF5AGrh3dsdW8p2E5jS4P8bDWZAoQTeeKB'
|
||||
];
|
||||
|
||||
var hash = new Buffer(TXIN.split('').reverse(), 'hex');
|
||||
var vout = parseInt(TXIN_N);
|
||||
var voutBuf = new Buffer(4);
|
||||
|
||||
voutBuf.writeUInt32LE(vout, 0);
|
||||
txin.o = Buffer.concat([hash, voutBuf]);
|
||||
txobj.ins.push(txin);
|
||||
|
||||
var addr = new Address(ADDR);
|
||||
var script = Script.createPubKeyHashOut(addr.payload());
|
||||
var valueNum = coinUtil.parseValue(VAL);
|
||||
var value = coinUtil.bigIntToValue(valueNum);
|
||||
|
||||
var txout = {
|
||||
v: value,
|
||||
s: script.getBuffer(),
|
||||
};
|
||||
txobj.outs.push(txout);
|
||||
|
||||
return new Transaction(txobj);
|
||||
|
||||
};
|
||||
|
||||
var peerman = new PeerManager();
|
||||
var peerman = new PeerManager({
|
||||
network: 'testnet'
|
||||
});
|
||||
peerman.addPeer(new Peer('127.0.0.1', 18333));
|
||||
|
||||
peerman.on('connect', function() {
|
||||
var conn = peerman.getActiveConnection();
|
||||
if (conn) {
|
||||
conn.sendTx(createTx());
|
||||
// define transaction output
|
||||
var outs = [{
|
||||
address: 'mhNCT9TwZAGF1tLPpZdqfkTmtBkY282YDW',
|
||||
amount: 0.1337
|
||||
}];
|
||||
// set change address
|
||||
var opts = {
|
||||
remainderOut: {
|
||||
address: 'n4g2TFaQo8UgedwpkYdcQFF6xE2Ei9Czvy'
|
||||
}
|
||||
};
|
||||
var tx = new TransactionBuilder(opts)
|
||||
.setUnspent(unspent)
|
||||
.setOutputs(outs)
|
||||
.sign(keys)
|
||||
.build();
|
||||
|
||||
/* Create and signing can be done in multiple steps:
|
||||
*
|
||||
* var builder = new bitcore.TransactionBuilder(opts)
|
||||
* .setUnspent(utxos)
|
||||
* .setOutputs(outs);
|
||||
*
|
||||
* // Sign with the first key
|
||||
* builder.sign(key1);
|
||||
* var tx = builder.build(); // Partially signed transaction
|
||||
*
|
||||
* // Sign with the second key
|
||||
* builder.sign(key2);
|
||||
* if (builder.isFullySigned()){
|
||||
* var tx = builder.build();
|
||||
* }
|
||||
*
|
||||
* var selectedUnspent = build.getSelectedUnspent(); // Retrieve selected unspent outputs from the transaction
|
||||
*/
|
||||
|
||||
var txid = tx.getHash().toString('hex');
|
||||
console.log('Created transaction with txid '+txid);
|
||||
var raw_tx = tx.serialize().toString('hex');
|
||||
console.log('Transaction raw hex dump:');
|
||||
console.log('-------------------------------------');
|
||||
console.log(raw_tx);
|
||||
console.log('-------------------------------------');
|
||||
// finally, send transaction to the bitcoin network
|
||||
conn.sendTx(tx);
|
||||
|
||||
// for now, the network won't respond in any case
|
||||
// (transaction accepted, transaction rejected)
|
||||
// in the future, we may listen to 'reject' message
|
||||
// see https://gist.github.com/gavinandresen/7079034
|
||||
}
|
||||
conn.on('reject', function() {
|
||||
console.log('Transaction Rejected');
|
||||
});
|
||||
});
|
||||
|
||||
peerman.start();
|
||||
|
||||
};
|
||||
|
||||
module.exports.run = run;
|
||||
|
|
Loading…
Reference in New Issue