Remove old tests.
This commit is contained in:
parent
e8d4786e48
commit
43d21e9f02
@ -1,28 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
|
|
||||||
var addrs = [
|
|
||||||
'1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
|
|
||||||
'1A1zP1eP5QGefi2DMPTfTL5SLmv7Dixxxx',
|
|
||||||
'A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
|
|
||||||
'1600 Pennsylvania Ave NW',
|
|
||||||
].map(function(addr) {
|
|
||||||
return new Address(addr);
|
|
||||||
});
|
|
||||||
|
|
||||||
addrs.forEach(function(addr) {
|
|
||||||
var valid = addr.isValid();
|
|
||||||
console.log(addr.data + ' is ' + (valid ? '' : 'not ') + 'valid');
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
var Armory = require('../lib/Armory');
|
|
||||||
var Address = require('../lib/Address');
|
|
||||||
|
|
||||||
// Initial public key can be retrieved from paper backup
|
|
||||||
|
|
||||||
var PublicX = '9df5 23e7 18b9 1f59 a790 2d46 999f 9357 ccf8 7208 24d4 3076 4516 b809 f7ab ce4e';
|
|
||||||
var PublicY = '66ba 5d21 4682 0dae 401d 9506 8437 2516 79f9 0c56 4186 cc50 07df c6d0 6989 1ff4';
|
|
||||||
var pubkey = '04' + PublicX.split(' ').join('') + PublicY.split(' ').join('');
|
|
||||||
|
|
||||||
// Chain code can be generated by entering paper backup
|
|
||||||
// on brainwallet.org/#chains or by using Armory.fromSeed() below
|
|
||||||
|
|
||||||
var chaincode = '84ac14bc4b388b33da099a0b4ee3b507284d99e1476639e36e5ca5e6af86481e';
|
|
||||||
|
|
||||||
var armory = new Armory(chaincode, pubkey);
|
|
||||||
|
|
||||||
console.log('Deriving public keys for');
|
|
||||||
console.log('------------------------');
|
|
||||||
console.log('Chain code: %s', chaincode);
|
|
||||||
console.log('Public key: %s', pubkey);
|
|
||||||
console.log('');
|
|
||||||
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
console.log(Address.fromPubKey(armory.pubkey).as('base58'));
|
|
||||||
armory = armory.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derive first public key and chain code from seed
|
|
||||||
var seed = [
|
|
||||||
'aagh hjfj sihk ietj giik wwai awtd uodh hnji',
|
|
||||||
'soss uaku egod utai itos fijj ihgi jhau jtoo'
|
|
||||||
];
|
|
||||||
|
|
||||||
console.log('');
|
|
||||||
console.log('');
|
|
||||||
console.log('Deriving public keys for');
|
|
||||||
console.log('------------------------');
|
|
||||||
console.log('Seed: %s', seed.join(' '));
|
|
||||||
console.log('');
|
|
||||||
|
|
||||||
// skip first public key
|
|
||||||
var a = Armory.fromSeed(seed.join('\n')).next();
|
|
||||||
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
console.log(Address.fromPubKey(a.pubkey).as('base58'));
|
|
||||||
a = a.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var mpk = '045a09a3286873a72f164476bde9d1d8e5c2bc044e35aa47eb6e798e325a86417f7c35b61d9905053533e0b4f2a26eca0330aadf21c638969e45aaace50e4c0c8784ac14bc4b388b33da099a0b4ee3b507284d99e1476639e36e5ca5e6af86481e';
|
|
||||||
|
|
||||||
console.log('');
|
|
||||||
console.log('');
|
|
||||||
console.log('Deriving public keys for');
|
|
||||||
console.log('------------------------');
|
|
||||||
console.log('Master Public Key: %s', mpk);
|
|
||||||
console.log('');
|
|
||||||
|
|
||||||
// skip first public key
|
|
||||||
var b = Armory.fromMasterPublicKey(mpk).next();
|
|
||||||
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
console.log(Address.fromPubKey(b.pubkey).as('base58'));
|
|
||||||
b = b.next();
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
var Peer = require('../lib/Peer');
|
|
||||||
var Connection = require('../lib/Connection');
|
|
||||||
var dns = require('dns');
|
|
||||||
|
|
||||||
// get a peer from dns seed
|
|
||||||
dns.resolve('dnsseed.bluematt.me', function(err, seeds) {
|
|
||||||
// use the first peer
|
|
||||||
var peer = new Peer(seeds[0], 8333);
|
|
||||||
|
|
||||||
//Custom peer:
|
|
||||||
//var peer = new Peer('180.153.139.246', '8888');
|
|
||||||
|
|
||||||
// create a connection without an existing socket
|
|
||||||
// but specify a socks5 proxy to create a socket
|
|
||||||
// that's bound to that proxy in it's place
|
|
||||||
var connection = new Connection(null, peer, {
|
|
||||||
proxy: {
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: 9050
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.open();
|
|
||||||
|
|
||||||
connection.on('connect', function(data) {
|
|
||||||
console.log('connected through socks5!');
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.on('error', function(err) {
|
|
||||||
console.log('There was an error running this example.');
|
|
||||||
console.log('Are you running Tor? Tor must running for this example to work.');
|
|
||||||
console.log('If you still get an error, you may need to use a different proxy from here:');
|
|
||||||
console.log('http://sockslist.net/');
|
|
||||||
//console.log(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
var run = function() {
|
|
||||||
bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore;
|
|
||||||
var networks = require('../networks');
|
|
||||||
var WalletKey = bitcore.WalletKey;
|
|
||||||
var Builder = bitcore.TransactionBuilder;
|
|
||||||
var opts = {
|
|
||||||
network: networks.testnet
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('## Network: ' + opts.network.name);
|
|
||||||
|
|
||||||
var input = {};
|
|
||||||
input.addr = "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp";
|
|
||||||
input.priv = "cS62Ej4SobZnpFQYN1PEEBr2KWf5sgRYYnELtumcG6WVCfxno39V";
|
|
||||||
|
|
||||||
// Complete with the corresponding UTXO you want to use
|
|
||||||
var utxos = [{
|
|
||||||
address: input.addr,
|
|
||||||
txid: "39c71ebda371f75f4b854a720eaf9898b237facf3c2b101b58cd4383a44a6adc",
|
|
||||||
vout: 1,
|
|
||||||
ts: 1396288753,
|
|
||||||
scriptPubKey: "76a914e867aad8bd361f57c50adc37a0c018692b5b0c9a88ac",
|
|
||||||
amount: 0.4296,
|
|
||||||
confirmations: 2
|
|
||||||
}];
|
|
||||||
|
|
||||||
var privs = [
|
|
||||||
"cP6JBHuQf7yqeqtdKRd22ibF3VehDv7G6BdzxSNABgrv3jFJUGoN",
|
|
||||||
"cQfRwF7XLSM5xGUpF8PZvob2MZyULvZPA2j5cat2RKDJrja7FtCZ",
|
|
||||||
"cUkYub4jtFVYymHh38yMMW36nJB4pXG5Pzd5QjResq79kAndkJcg",
|
|
||||||
"cMyBgowsyrJRufoKWob73rMQB1PBqDdwFt8z4TJ6APN2HkmX1Ttm",
|
|
||||||
"cN9yZCom6hAZpHtCp8ovE1zFa7RqDf3Cr4W6AwH2tp59Jjh9JcXu",
|
|
||||||
];
|
|
||||||
|
|
||||||
var pubkeys = []
|
|
||||||
privs.forEach(function(p) {
|
|
||||||
var wk = new WalletKey(opts);
|
|
||||||
wk.fromObj({
|
|
||||||
priv: p
|
|
||||||
});
|
|
||||||
pubkeys.push(bitcore.buffertools.toHex(wk.privKey.public));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var outs = [{
|
|
||||||
nreq: 3,
|
|
||||||
pubkeys: pubkeys,
|
|
||||||
amount: 0.05
|
|
||||||
}];
|
|
||||||
var tx = new Builder(opts)
|
|
||||||
.setUnspent(utxos)
|
|
||||||
.setOutputs(outs)
|
|
||||||
.sign([input.priv])
|
|
||||||
.build();
|
|
||||||
var txHex = tx.serialize().toString('hex');
|
|
||||||
console.log('1) SEND TO MULSISIG TX: ', txHex);
|
|
||||||
console.log('[this example originally generated TXID: e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5 on testnet]\n\n\thttp://test.bitcore.io/tx/e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5\n\n');
|
|
||||||
|
|
||||||
|
|
||||||
//save scriptPubKey
|
|
||||||
var scriptPubKey = tx.outs[0].s.toString('hex');
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* REDDEEM TX
|
|
||||||
*/
|
|
||||||
var utxos2 = [{
|
|
||||||
address: input.addr,
|
|
||||||
txid: "e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5",
|
|
||||||
vout: 0,
|
|
||||||
ts: 1396288753,
|
|
||||||
scriptPubKey: scriptPubKey,
|
|
||||||
amount: 0.05,
|
|
||||||
confirmations: 2
|
|
||||||
}];
|
|
||||||
|
|
||||||
outs = [{
|
|
||||||
address: input.addr,
|
|
||||||
amount: 0.04
|
|
||||||
}];
|
|
||||||
var b = new Builder(opts)
|
|
||||||
.setUnspent(utxos2)
|
|
||||||
.setOutputs(outs)
|
|
||||||
.sign(privs);
|
|
||||||
|
|
||||||
|
|
||||||
tx = b.build();
|
|
||||||
|
|
||||||
|
|
||||||
var txHex = tx.serialize().toString('hex');
|
|
||||||
console.log('2) REDEEM SCRIPT: ', txHex);
|
|
||||||
console.log('=> Is signed status:', b.isFullySigned(), tx.countInputMissingSignatures(0));
|
|
||||||
|
|
||||||
console.log('[this example originally generated TXID: 1eb388977b2de99562eb0fbcc661a100eaffed99c53bfcfebe5a087002039b83 on testnet]\n\n\thttp://test.bitcore.io/tx/1eb388977b2de99562eb0fbcc661a100eaffed99c53bfcfebe5a087002039b83');
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is just for browser & mocha compatibility
|
|
||||||
if (typeof module !== 'undefined') {
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
|
|
||||||
////
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
var run = function() {
|
|
||||||
bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore;
|
|
||||||
|
|
||||||
var priv = 'cTgGUrcro89yUtKeG6gHBAS14r3qp25KwTTxG9d4kEzcFxecuZDm';
|
|
||||||
var amt = '0.005';
|
|
||||||
var toAddress = 'myuAQcCc1REUgXGsCTiYhZvPPc3XxZ36G1';
|
|
||||||
var changeAddressString = 'moDz3jEo9q7CxjBDjmb13sL4SKkgo2AACE';
|
|
||||||
|
|
||||||
var utxos = [{
|
|
||||||
address: "mqSjTad2TKbPcKQ3Jq4kgCkKatyN44UMgZ",
|
|
||||||
txid: "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
|
|
||||||
vout: 1,
|
|
||||||
ts: 1394719301,
|
|
||||||
scriptPubKey: "76a9146ce4e1163eb18939b1440c42844d5f0261c0338288ac",
|
|
||||||
amount: 0.01,
|
|
||||||
confirmations: 2
|
|
||||||
}];
|
|
||||||
|
|
||||||
console.log('TX Data: BTC:' + amt + ' => ' + toAddress + ', change To:' + changeAddressString);
|
|
||||||
console.log('Unspends Outputs:', utxos);
|
|
||||||
|
|
||||||
|
|
||||||
var outs = [{
|
|
||||||
address: toAddress,
|
|
||||||
amount: amt
|
|
||||||
}];
|
|
||||||
var keys = [priv];
|
|
||||||
var opts = {
|
|
||||||
remainderOut: {
|
|
||||||
address: changeAddressString
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var Builder = bitcore.TransactionBuilder;
|
|
||||||
|
|
||||||
var tx = new Builder(opts)
|
|
||||||
.setUnspent(utxos)
|
|
||||||
.setOutputs(outs)
|
|
||||||
.sign(keys)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/* create and signing can be done in multiple steps using:
|
|
||||||
*
|
|
||||||
* var builder = new bitcore.TransactionBuilder(opts)
|
|
||||||
* .setUnspent(utxos)
|
|
||||||
* .setOutputs(outs);
|
|
||||||
*
|
|
||||||
* builder.sign(key1);
|
|
||||||
* builder.sign(key2);
|
|
||||||
* ...
|
|
||||||
* if (builder.isFullySigned()){
|
|
||||||
* var tx = builder.build();
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* The selected Unspent Outputs for the transaction can be retrieved with:
|
|
||||||
*
|
|
||||||
* var selectedUnspent = build.getSelectedUnspent();
|
|
||||||
*/
|
|
||||||
|
|
||||||
var txHex = tx.serialize().toString('hex');
|
|
||||||
console.log('TX HEX IS: ', txHex);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is just for browser & mocha compatibility
|
|
||||||
if (typeof module !== 'undefined') {
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
|
|
||||||
////
|
|
||||||
@ -1,151 +0,0 @@
|
|||||||
var run = function() {
|
|
||||||
bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore;
|
|
||||||
var networks = require('../networks');
|
|
||||||
var WalletKey = bitcore.WalletKey;
|
|
||||||
var Script = bitcore.Script;
|
|
||||||
var Builder = bitcore.TransactionBuilder;
|
|
||||||
var opts = {
|
|
||||||
network: networks.testnet
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('## Network: ' + opts.network.name);
|
|
||||||
|
|
||||||
var input = {};
|
|
||||||
input.addr = "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp";
|
|
||||||
input.priv = "cS62Ej4SobZnpFQYN1PEEBr2KWf5sgRYYnELtumcG6WVCfxno39V";
|
|
||||||
|
|
||||||
// Complete with the corresponding UTXO you want to use
|
|
||||||
var utxos = [{
|
|
||||||
address: "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp",
|
|
||||||
txid: "e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5",
|
|
||||||
vout: 1,
|
|
||||||
ts: 1396290442,
|
|
||||||
scriptPubKey: "76a914e867aad8bd361f57c50adc37a0c018692b5b0c9a88ac",
|
|
||||||
amount: 0.3795,
|
|
||||||
confirmations: 7
|
|
||||||
}];
|
|
||||||
|
|
||||||
var privs = [
|
|
||||||
"cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA",
|
|
||||||
"cVf32m9MR4vxcPwKNJuPepUe8XrHD2z63eCk76d6njRGyCkXpkSM",
|
|
||||||
"cQ2sVRFX4jQYMLhWyzz6jTQ2xju51P36968ecXnPhRLKLH677eKR",
|
|
||||||
"cSw7x9ERcmeWCU3yVBT6Nz7b9JiZ5yjUB7JMhBUv9UM7rSaDpwX9",
|
|
||||||
"cRQBM8qM4ZXJGP1De4D5RtJm7Q6FNWQSMx7YExxzgn2ehjM3haxW",
|
|
||||||
];
|
|
||||||
|
|
||||||
var pubkeys = []
|
|
||||||
privs.forEach(function(p) {
|
|
||||||
var wk = new WalletKey(opts);
|
|
||||||
wk.fromObj({
|
|
||||||
priv: p
|
|
||||||
});
|
|
||||||
pubkeys.push(bitcore.buffertools.toHex(wk.privKey.public));
|
|
||||||
});
|
|
||||||
|
|
||||||
// multisig p2sh
|
|
||||||
var opts = {
|
|
||||||
nreq: 3,
|
|
||||||
pubkeys: pubkeys
|
|
||||||
};
|
|
||||||
|
|
||||||
// p2scriphash p2sh
|
|
||||||
//var opts = [{address: an_address}];
|
|
||||||
|
|
||||||
var info = Builder.infoForP2sh(opts, 'testnet');
|
|
||||||
var p2shScript = info.scriptBufHex;
|
|
||||||
var p2shAddress = info.address;
|
|
||||||
|
|
||||||
|
|
||||||
var outs = [{
|
|
||||||
address: p2shAddress,
|
|
||||||
amount: 0.05
|
|
||||||
}];
|
|
||||||
var tx = new Builder(opts)
|
|
||||||
.setUnspent(utxos)
|
|
||||||
.setOutputs(outs)
|
|
||||||
.sign([input.priv])
|
|
||||||
.build();
|
|
||||||
|
|
||||||
var txHex = tx.serialize().toString('hex');
|
|
||||||
|
|
||||||
|
|
||||||
console.log('## p2sh address: ' + p2shAddress); //TODO
|
|
||||||
console.log('\n1) SEND TO P2SH TX: ', txHex);
|
|
||||||
console.log('[this example originally generated TXID: c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7 on testnet]\n\n\thttp://test.bitcore.io/tx/c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7\n\n');
|
|
||||||
|
|
||||||
//save scriptPubKey
|
|
||||||
var scriptPubKey = tx.outs[0].s.toString('hex');
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* REDDEEM TX
|
|
||||||
*/
|
|
||||||
var utxos2 = [{
|
|
||||||
address: p2shAddress,
|
|
||||||
txid: "c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7",
|
|
||||||
vout: 0,
|
|
||||||
ts: 1396375187,
|
|
||||||
scriptPubKey: scriptPubKey,
|
|
||||||
amount: 0.05,
|
|
||||||
confirmations: 1
|
|
||||||
}];
|
|
||||||
|
|
||||||
outs = [{
|
|
||||||
address: input.addr,
|
|
||||||
amount: 0.04
|
|
||||||
}];
|
|
||||||
|
|
||||||
var hashMap = {};
|
|
||||||
hashMap[p2shAddress] = p2shScript;
|
|
||||||
|
|
||||||
var b = new Builder(opts)
|
|
||||||
.setUnspent(utxos2)
|
|
||||||
.setHashToScriptMap(hashMap)
|
|
||||||
.setOutputs(outs)
|
|
||||||
.sign(privs);
|
|
||||||
|
|
||||||
tx = b.build();
|
|
||||||
|
|
||||||
|
|
||||||
console.log('Builder:');
|
|
||||||
console.log('\tSignatures:' + tx.countInputMissingSignatures(0));
|
|
||||||
console.log('\t#isFullySigned:' + b.isFullySigned());
|
|
||||||
|
|
||||||
console.log('TX:');
|
|
||||||
console.log('\t #isComplete:' + tx.isComplete());
|
|
||||||
|
|
||||||
var txHex = tx.serialize().toString('hex');
|
|
||||||
console.log('2) REDEEM SCRIPT: ', txHex);
|
|
||||||
console.log('[this example originally generated TXID: 8284aa3b6f9c71c35ecb1d61d05ae78c8ca1f36940eaa615b50584dfc3d95cb7 on testnet]\n\n\thttp://test.bitcore.io/tx/8284aa3b6f9c71c35ecb1d61d05ae78c8ca1f36940eaa615b50584dfc3d95cb7\n\n');
|
|
||||||
|
|
||||||
/*
|
|
||||||
// To send TX with RPC:
|
|
||||||
var RpcClient = bitcore.RpcClient;
|
|
||||||
var config = {
|
|
||||||
protocol: 'http',
|
|
||||||
user: 'user',
|
|
||||||
pass: 'pass',
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: '18332',
|
|
||||||
};
|
|
||||||
var rpc = new RpcClient(config);
|
|
||||||
rpc.sendRawTransaction(txHex, function(err, ret) {
|
|
||||||
console.log('err', err); //TODO
|
|
||||||
console.log('ret', ret); //TODO
|
|
||||||
process.exit(-1);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// This is just for browser & mocha compatibility
|
|
||||||
if (typeof module !== 'undefined') {
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var networks = require('../networks');
|
|
||||||
var WalletKey = bitcore.WalletKey;
|
|
||||||
|
|
||||||
var opts = {
|
|
||||||
network: networks.testnet
|
|
||||||
};
|
|
||||||
|
|
||||||
function print(wk) {
|
|
||||||
|
|
||||||
console.log('\n## Network: ' + wk.network.name);
|
|
||||||
console.log('\t * Hex Representation');
|
|
||||||
console.log('\tPrivate: ' + bitcore.buffertools.toHex(wk.privKey.private));
|
|
||||||
console.log('\tPublic : ' + bitcore.buffertools.toHex(wk.privKey.public));
|
|
||||||
console.log('\tPublic Compressed : ' + (wk.privKey.compressed ? 'Yes' : 'No'));
|
|
||||||
|
|
||||||
var wkObj = wk.storeObj();
|
|
||||||
console.log('\n\t * WalletKey Store Object');
|
|
||||||
console.log('\tPrivate: ' + wkObj.priv);
|
|
||||||
console.log('\tPublic : ' + wkObj.pub);
|
|
||||||
console.log('\tAddr : ' + wkObj.addr);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Generate a new one (compressed public key, compressed WIF flag)
|
|
||||||
var wk = new WalletKey(opts);
|
|
||||||
wk.generate();
|
|
||||||
print(wk);
|
|
||||||
|
|
||||||
//Generate from private Key WIF. Compressed status taken from WIF.
|
|
||||||
var wk2 = new WalletKey(opts);
|
|
||||||
wk2.fromObj({
|
|
||||||
priv: 'cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA'
|
|
||||||
});
|
|
||||||
print(wk2);
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var networks = require('../networks');
|
|
||||||
var Script = bitcore.Script;
|
|
||||||
var WalletKey = bitcore.WalletKey;
|
|
||||||
var buffertools = bitcore.buffertools;
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var util = bitcore.util;
|
|
||||||
var opts = {
|
|
||||||
network: networks.testnet
|
|
||||||
};
|
|
||||||
|
|
||||||
var p = console.log;
|
|
||||||
|
|
||||||
var wk = new WalletKey(opts);
|
|
||||||
wk.generate();
|
|
||||||
var wkObj = wk.storeObj();
|
|
||||||
|
|
||||||
var s = Script.createPubKeyOut(wk.privKey.public);
|
|
||||||
p('\nScript PubKey:');
|
|
||||||
p('\tHex : ' + buffertools.toHex(s.buffer));
|
|
||||||
p('\tHuman : ' + s.toHumanReadable());
|
|
||||||
p('\tKey -------------------------------');
|
|
||||||
console.log('\tPrivate: ' + wkObj.priv);
|
|
||||||
console.log('\tPublic : ' + wkObj.pub);
|
|
||||||
console.log('\tAddr : ' + wkObj.addr);
|
|
||||||
|
|
||||||
s = Script.createPubKeyHashOut(wk.privKey.public);
|
|
||||||
p('\nScript PubKeyHash:');
|
|
||||||
p('\tHex : ' + buffertools.toHex(s.buffer));
|
|
||||||
p('\tHuman : ' + s.toHumanReadable());
|
|
||||||
p('\tKey -------------------------------');
|
|
||||||
console.log('\tPrivate: ' + wkObj.priv);
|
|
||||||
console.log('\tPublic : ' + wkObj.pub);
|
|
||||||
console.log('\tAddr : ' + wkObj.addr);
|
|
||||||
|
|
||||||
var wks = [];
|
|
||||||
var pubs = [];
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
wks[i] = new WalletKey(opts);
|
|
||||||
wks[i].generate();
|
|
||||||
pubs.push(wks[i].privKey.public);
|
|
||||||
}
|
|
||||||
|
|
||||||
s = Script.createMultisig(3, pubs);
|
|
||||||
p('\nScript MultiSig (3 out of 5 required signatures):');
|
|
||||||
p('\tHex : ' + buffertools.toHex(s.buffer));
|
|
||||||
p('\tHuman : ' + s.toHumanReadable());
|
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
|
||||||
wkObj = wks[i].storeObj();
|
|
||||||
p('\tKey [' + i + '] -------------------------------');
|
|
||||||
console.log('\tPrivate: ' + wkObj.priv);
|
|
||||||
console.log('\tPublic : ' + wkObj.pub);
|
|
||||||
console.log('\tAddr : ' + wkObj.addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
var hash = util.sha256ripe160(s.buffer);
|
|
||||||
|
|
||||||
s = Script.createP2SH(hash);
|
|
||||||
p('\nScript P2SH:');
|
|
||||||
p('\tHex : ' + buffertools.toHex(s.buffer));
|
|
||||||
p('\tHuman : ' + s.toHumanReadable());
|
|
||||||
p('\tScript Hash: ' + buffertools.toHex(hash));
|
|
||||||
var a = new Address(networks.livenet.P2SHVersion, hash);
|
|
||||||
p('\tp2sh Addr: ' + a.toString());
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
var run = function() {
|
|
||||||
bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore;
|
|
||||||
|
|
||||||
console.log('ECIES: Elliptic Curve Integrated Encryption Scheme');
|
|
||||||
console.log('A way of encrypting with a public key and decrypting with a private key.');
|
|
||||||
|
|
||||||
var key = bitcore.Key.generateSync();
|
|
||||||
console.log('Private key: ' + key.private.toString('hex'));
|
|
||||||
console.log('Public key: ' + key.public.toString('hex'));
|
|
||||||
|
|
||||||
var message = new Buffer('This is a message to be encrypted');
|
|
||||||
console.log('Message: "' + message.toString() + '"');
|
|
||||||
|
|
||||||
var encrypted = bitcore.ECIES.encrypt(key.public, message);
|
|
||||||
console.log('Encrypted (with public key): ' + encrypted.toString('hex'));
|
|
||||||
|
|
||||||
var decrypted = bitcore.ECIES.decrypt(key.private, encrypted);
|
|
||||||
console.log('Decrypted (with private key): "' + decrypted.toString() + '"');
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// This is just for browser & mocha compatibility
|
|
||||||
if (typeof module !== 'undefined') {
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
var Electrum = require('../lib/Electrum');
|
|
||||||
var Address = require('../lib/Address');
|
|
||||||
|
|
||||||
var mpk = '92eea4d2f5263651db9e3222caded1fd4c89772f79a7c03fb6afc00e9d2c9d2ed9b86c2c95fc1171e49163079dacb7f048b3c509a27a490e1df9e7128362d468';
|
|
||||||
|
|
||||||
mpk = new Electrum(mpk);
|
|
||||||
|
|
||||||
var key0 = mpk.generatePubKey(0);
|
|
||||||
var addr0 = Address.fromPubKey(key0);
|
|
||||||
|
|
||||||
console.log(addr0.as('base58'));
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
var run = function() {
|
|
||||||
bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore;
|
|
||||||
var HierarchicalKey = bitcore.HierarchicalKey;
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var networks = bitcore.networks;
|
|
||||||
var coinUtil = bitcore.util;
|
|
||||||
var crypto = require('crypto');
|
|
||||||
|
|
||||||
console.log('HierarchicalKey: Hierarchical Deterministic Wallets (BIP32)');
|
|
||||||
console.log('https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\n');
|
|
||||||
console.log('1) Make new hkey from randomly generated new seed');
|
|
||||||
|
|
||||||
var randomBytes = crypto.randomBytes(32);
|
|
||||||
var hkey = HierarchicalKey.seed(randomBytes);
|
|
||||||
console.log('master extended private key: ' + hkey.extendedPrivateKeyString());
|
|
||||||
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
|
|
||||||
console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString());
|
|
||||||
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
console.log('2) Make new hkey from known seed');
|
|
||||||
var knownBytes = coinUtil.sha256('do not use this password as a brain wallet');
|
|
||||||
var hkey = HierarchicalKey.seed(knownBytes);
|
|
||||||
console.log('master extended private key: ' + hkey.extendedPrivateKeyString());
|
|
||||||
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
|
|
||||||
console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString());
|
|
||||||
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
console.log('3) Make new hkey from known master private key');
|
|
||||||
var knownMasterPrivateKey = 'xprv9s21ZrQH143K2LvayFZWVVTomiDKheKWvnupDB8fmjKwxkKG47uvzmFa3vCXoy9fxPJhRYsU19apVfexvMeLpJQuF2XtX1zRF3eao9GqqaQ';
|
|
||||||
var hkey = new HierarchicalKey(knownMasterPrivateKey);
|
|
||||||
console.log('master extended private key: ' + hkey.extendedPrivateKeyString());
|
|
||||||
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
|
|
||||||
console.log('m/0/3/5 extended private key: ' + hkey.derive('m/0/3/5').extendedPrivateKeyString());
|
|
||||||
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
console.log('4) Make new hkey from known master public key');
|
|
||||||
var knownMasterPublicKey = 'xpub661MyMwAqRbcGpiFufipqsKKBG1NHNwfJKishAEFNqJ6ryLcKeKyFNEZces7gMWd4XGg4uUhXy8DS64o1oPGUECVHeLq957Txjwagxt475H';
|
|
||||||
var hkey = new HierarchicalKey(knownMasterPublicKey);
|
|
||||||
console.log('master extended private key: cannot derive');
|
|
||||||
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
|
|
||||||
console.log('m/0/3/5 extended private key: cannot derive');
|
|
||||||
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
console.log('5) Make new hkey from known derived public key');
|
|
||||||
var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3';
|
|
||||||
var hkey = new HierarchicalKey(knownPublicKey);
|
|
||||||
console.log('master extended private key: cannot derive');
|
|
||||||
console.log('master extended public key: ' + hkey.extendedPublicKeyString());
|
|
||||||
console.log('m/0/3/5 extended private key: cannot derive');
|
|
||||||
console.log('m/0/3/5 extended public key: ' + hkey.derive('m/0/3/5').extendedPublicKeyString());
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
console.log('6) Make a bunch of new addresses from known public key');
|
|
||||||
var knownPublicKey = 'xpub6CZei1p2zk68UwkcBDqzRonLHJWAiPZZ58sMgHJAn9fmpmnPayVEAvAs3XvTSUMZ1J8dNaxnv4wnt7YpRKr6BsqeWbW8msqeuuhiSzsQEC3';
|
|
||||||
var hkey = new HierarchicalKey(knownPublicKey);
|
|
||||||
console.log('m/0 address: ' + Address.fromPubKey(hkey.derive('m/0').eckey.public).toString());
|
|
||||||
//console.log('m/1 extended public key: ' + hkey.derive('m/1').extendedPublicKeyString());
|
|
||||||
console.log('m/1 address: ' + Address.fromPubKey(hkey.derive('m/1').eckey.public).toString());
|
|
||||||
//console.log('m/2 extended public key: ' + hkey.derive('m/2').extendedPublicKeyString());
|
|
||||||
console.log('m/2 address: ' + Address.fromPubKey(hkey.derive('m/2').eckey.public).toString());
|
|
||||||
//console.log('m/3 extended public key: ' + hkey.derive('m/3').extendedPublicKeyString());
|
|
||||||
console.log('m/3 address: ' + Address.fromPubKey(hkey.derive('m/3').eckey.public).toString());
|
|
||||||
console.log('...');
|
|
||||||
//console.log('m/100 extended public key: ' + hkey.derive('m/100').extendedPublicKeyString());
|
|
||||||
console.log('m/100 address: ' + Address.fromPubKey(hkey.derive('m/100').eckey.public).toString());
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// This is just for browser & mocha compatibility
|
|
||||||
if (typeof module !== 'undefined') {
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var NetworkMonitor = bitcore.NetworkMonitor;
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
networkName: 'testnet',
|
|
||||||
host: 'localhost',
|
|
||||||
port: 18333
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var nm = new NetworkMonitor.create(config);
|
|
||||||
// monitor incoming transactions to http://tpfaucet.appspot.com/ donation address
|
|
||||||
nm.incoming('msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', function(tx) {
|
|
||||||
console.log('Donation to tpfaucet! '+JSON.stringify(tx.getStandardizedObject()));
|
|
||||||
});
|
|
||||||
|
|
||||||
// connect to bitcoin network and start listening
|
|
||||||
nm.start();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var coinUtil = bitcore.util;
|
|
||||||
var Script = bitcore.Script;
|
|
||||||
var network = bitcore.networks.testnet;
|
|
||||||
|
|
||||||
var script = 'OP_RETURN 58434c524e4748530000000000000000000000010000000005f5e100';
|
|
||||||
var s = Script.fromHumanReadable(script);
|
|
||||||
var result = (s.classify() == Script.TX_RETURN)
|
|
||||||
console.log("Is op_return:", result);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
# Running the Payment Protocol Demo
|
|
||||||
|
|
||||||
## Node
|
|
||||||
|
|
||||||
The node payment protocol demonstration will run automatically via:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
$ node examples/PayPro
|
|
||||||
```
|
|
||||||
|
|
||||||
You will see the server and customer logs output in the terminal.
|
|
||||||
|
|
||||||
## Browser
|
|
||||||
|
|
||||||
To run our payment protocol demonstration in the browser, you may run:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
$ node examples/PayPro/server.js -b -p 8080
|
|
||||||
```
|
|
||||||
|
|
||||||
This will start the payment protocol demonstration server in browser mode,
|
|
||||||
which serves outputs in the payment protocol request (don't worry, it doesn't
|
|
||||||
ask for *too* many testnet coins).
|
|
||||||
|
|
||||||
Once the server is started, you can visit it in your browser:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
$ chromium https://localhost:8080/
|
|
||||||
```
|
|
||||||
|
|
||||||
You will see a simple checkout page to buy some imaginary products. Once you
|
|
||||||
press checkout, you will see all the server and client logs in the browser as
|
|
||||||
well as the terminal.
|
|
||||||
|
|
||||||
If you're connected to enough peers, your transaction will be broadcast
|
|
||||||
throughout the bitcoin testnet network and hopefully ACKed by your peers.
|
|
||||||
|
|
||||||
## Logs
|
|
||||||
|
|
||||||
Your logs may ultimately look something like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
Customer: Our payment was acknowledged!
|
|
||||||
Customer: Message from Merchant: Thank you for your payment!
|
|
||||||
Customer: Payment sent successfully.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Changing the server address contained in outputs
|
|
||||||
|
|
||||||
If you want to alter the address or public key the testnet coins get sent to by
|
|
||||||
the payment server, you can pass in the `--pubkey` or `--address` options.
|
|
||||||
`address` has to be a testnet address, whereas `pubkey` is a hex encoded public
|
|
||||||
key. The `--privkey` option is also available in the standard bitcoind privkey
|
|
||||||
format.
|
|
||||||
|
|
||||||
## Other Options
|
|
||||||
|
|
||||||
If you you're not connected to enough peers to broadcast your transaction (by
|
|
||||||
default, this example only connects to the core seed peers), you can enable
|
|
||||||
peer discovery in bitcore by passing the `--discovery` (`-d`) argument onto the
|
|
||||||
server command line.
|
|
||||||
|
|
||||||
If you don't want to actually broadcast your transaction and want to keep your
|
|
||||||
testnet coins, you can pass `--no-tx` on the server command line.
|
|
||||||
|
|
||||||
If you don't want the tests to run automatically and simply host the payment
|
|
||||||
server, simply pass `--browser` (`-b`) as mentioned above.
|
|
||||||
|
|
||||||
## Using the example in a modular manner
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var server = require('bitcore/examples/PayPro');
|
|
||||||
server.listen(8080);
|
|
||||||
```
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../../browser/bundle.js
|
|
||||||
@ -1,515 +0,0 @@
|
|||||||
/**
|
|
||||||
* Payment-Customer - A Payment Protocol demonstration.
|
|
||||||
* This file will run in node or the browser.
|
|
||||||
* Copyright (c) 2014, BitPay
|
|
||||||
* https://github.com/bitpay/bitcore
|
|
||||||
*/
|
|
||||||
|
|
||||||
;(function() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Global
|
|
||||||
*/
|
|
||||||
|
|
||||||
var window = this;
|
|
||||||
var global = this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Platform
|
|
||||||
*/
|
|
||||||
|
|
||||||
var isNode = !!(typeof process === 'object' && process && process.versions.node);
|
|
||||||
|
|
||||||
// Disable strictSSL
|
|
||||||
if (isNode) {
|
|
||||||
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dependencies
|
|
||||||
*/
|
|
||||||
|
|
||||||
var bitcore = isNode
|
|
||||||
? require('../../')
|
|
||||||
: require('bitcore');
|
|
||||||
var PayPro = bitcore.PayPro;
|
|
||||||
var Transaction = bitcore.Transaction;
|
|
||||||
var TransactionBuilder = bitcore.TransactionBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variables
|
|
||||||
*/
|
|
||||||
|
|
||||||
var port = 8080;
|
|
||||||
|
|
||||||
if (isNode) {
|
|
||||||
var argv = require('optimist').argv;
|
|
||||||
if (argv.p || argv.port) {
|
|
||||||
port = +argv.p || +argv.port;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port = +window.location.port || 443;
|
|
||||||
}
|
|
||||||
|
|
||||||
var merchant = isNode
|
|
||||||
? parseMerchantURI(argv.m || argv.u || argv._[0])
|
|
||||||
: parseMerchantURI(window.merchantURI);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send Payment
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (isNode) {
|
|
||||||
var Buffer = global.Buffer;
|
|
||||||
} else {
|
|
||||||
var Buffer = bitcore.Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
function request(options, callback) {
|
|
||||||
if (typeof options === 'string') {
|
|
||||||
options = { uri: options };
|
|
||||||
}
|
|
||||||
|
|
||||||
options.method = options.method || 'GET';
|
|
||||||
options.headers = options.headers || {};
|
|
||||||
|
|
||||||
if (!isNode) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.open(options.method, options.uri, true);
|
|
||||||
|
|
||||||
Object.keys(options.headers).forEach(function(key) {
|
|
||||||
var val = options.headers[key];
|
|
||||||
if (key === 'Content-Length') return;
|
|
||||||
if (key === 'Content-Transfer-Encoding') return;
|
|
||||||
xhr.setRequestHeader(key, val);
|
|
||||||
});
|
|
||||||
|
|
||||||
// For older browsers:
|
|
||||||
// xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
|
||||||
|
|
||||||
// Newer browsers:
|
|
||||||
xhr.responseType = 'arraybuffer';
|
|
||||||
|
|
||||||
xhr.onload = function(event) {
|
|
||||||
var response = xhr.response;
|
|
||||||
var buf = new Uint8Array(response);
|
|
||||||
return callback(null, xhr, buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (options.body) {
|
|
||||||
xhr.send(options.body);
|
|
||||||
} else {
|
|
||||||
xhr.send(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return require('request')(options, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendPayment(msg, callback) {
|
|
||||||
if (arguments.length === 1) {
|
|
||||||
callback = msg;
|
|
||||||
msg = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return request({
|
|
||||||
method: 'GET',
|
|
||||||
uri: 'https://localhost:' + port + '/-/request',
|
|
||||||
headers: {
|
|
||||||
'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
|
|
||||||
+ ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
|
|
||||||
'Content-Type': 'application/octet-stream',
|
|
||||||
'Content-Length': 0
|
|
||||||
},
|
|
||||||
encoding: null
|
|
||||||
}, function(err, res, body) {
|
|
||||||
if (err) return callback(err);
|
|
||||||
|
|
||||||
body = PayPro.PaymentRequest.decode(body);
|
|
||||||
|
|
||||||
var pr = new PayPro();
|
|
||||||
pr = pr.makePaymentRequest(body);
|
|
||||||
|
|
||||||
var ver = pr.get('payment_details_version');
|
|
||||||
var pki_type = pr.get('pki_type');
|
|
||||||
var pki_data = pr.get('pki_data');
|
|
||||||
var details = pr.get('serialized_payment_details');
|
|
||||||
var sig = pr.get('signature');
|
|
||||||
|
|
||||||
// Verify Signature
|
|
||||||
var verified = pr.verify();
|
|
||||||
|
|
||||||
if (!verified) {
|
|
||||||
return callback(new Error('Server sent a bad signature.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
details = PayPro.PaymentDetails.decode(details);
|
|
||||||
var pd = new PayPro();
|
|
||||||
pd = pd.makePaymentDetails(details);
|
|
||||||
var network = pd.get('network');
|
|
||||||
var outputs = pd.get('outputs');
|
|
||||||
var time = pd.get('time');
|
|
||||||
var expires = pd.get('expires');
|
|
||||||
var memo = pd.get('memo');
|
|
||||||
var payment_url = pd.get('payment_url');
|
|
||||||
var merchant_data = pd.get('merchant_data');
|
|
||||||
|
|
||||||
print('You are currently on this BTC network:');
|
|
||||||
print(network);
|
|
||||||
print('The server sent you a message:');
|
|
||||||
print(memo);
|
|
||||||
|
|
||||||
var refund_outputs = [];
|
|
||||||
|
|
||||||
var rpo = new PayPro();
|
|
||||||
rpo = rpo.makeOutput();
|
|
||||||
rpo.set('amount', 0);
|
|
||||||
rpo.set('script', new Buffer([
|
|
||||||
118, // OP_DUP
|
|
||||||
169, // OP_HASH160
|
|
||||||
76, // OP_PUSHDATA1
|
|
||||||
20, // number of bytes
|
|
||||||
0xcf,
|
|
||||||
0xbe,
|
|
||||||
0x41,
|
|
||||||
0xf4,
|
|
||||||
0xa5,
|
|
||||||
0x18,
|
|
||||||
0xed,
|
|
||||||
0xc2,
|
|
||||||
0x5a,
|
|
||||||
0xf7,
|
|
||||||
0x1b,
|
|
||||||
0xaf,
|
|
||||||
0xc7,
|
|
||||||
0x2f,
|
|
||||||
0xb6,
|
|
||||||
0x1b,
|
|
||||||
0xfc,
|
|
||||||
0xfc,
|
|
||||||
0x4f,
|
|
||||||
0xcd,
|
|
||||||
136, // OP_EQUALVERIFY
|
|
||||||
172 // OP_CHECKSIG
|
|
||||||
]));
|
|
||||||
|
|
||||||
refund_outputs.push(rpo.message);
|
|
||||||
|
|
||||||
// We send this to the serve after receiving a PaymentRequest
|
|
||||||
var pay = new PayPro();
|
|
||||||
pay = pay.makePayment();
|
|
||||||
pay.set('merchant_data', merchant_data);
|
|
||||||
pay.set('transactions', [createTX(outputs)]);
|
|
||||||
pay.set('refund_to', refund_outputs);
|
|
||||||
|
|
||||||
msg = msg || 'Hi server, I would like to give you some money.';
|
|
||||||
|
|
||||||
if (isNode && argv.memo) {
|
|
||||||
msg = argv.memo;
|
|
||||||
}
|
|
||||||
|
|
||||||
pay.set('memo', msg);
|
|
||||||
pay = pay.serialize();
|
|
||||||
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
uri: payment_url,
|
|
||||||
headers: {
|
|
||||||
// BIP-71
|
|
||||||
'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
|
|
||||||
+ ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
|
|
||||||
'Content-Type': PayPro.PAYMENT_CONTENT_TYPE,
|
|
||||||
'Content-Length': pay.length + '',
|
|
||||||
'Content-Transfer-Encoding': 'binary'
|
|
||||||
},
|
|
||||||
body: pay,
|
|
||||||
encoding: null
|
|
||||||
}, function(err, res, body) {
|
|
||||||
if (err) return callback(err);
|
|
||||||
body = PayPro.PaymentACK.decode(body);
|
|
||||||
var ack = new PayPro();
|
|
||||||
ack = ack.makePaymentACK(body);
|
|
||||||
var payment = ack.get('payment');
|
|
||||||
var memo = ack.get('memo');
|
|
||||||
print('Our payment was acknowledged!');
|
|
||||||
print('Message from Merchant: %s', memo);
|
|
||||||
payment = PayPro.Payment.decode(payment);
|
|
||||||
var pay = new PayPro();
|
|
||||||
payment = pay.makePayment(payment);
|
|
||||||
print(payment);
|
|
||||||
var tx = payment.message.transactions[0];
|
|
||||||
if (tx.buffer) {
|
|
||||||
tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
|
|
||||||
var ptx = new bitcore.Transaction();
|
|
||||||
|
|
||||||
var parser = new bitcore.BinaryParser(tx.buffer);
|
|
||||||
ptx.parse(parser);
|
|
||||||
// ptx.parse(tx.buffer);
|
|
||||||
|
|
||||||
tx = ptx;
|
|
||||||
}
|
|
||||||
var txid = tx.getHash().toString('hex');
|
|
||||||
print('First payment txid: %s', txid);
|
|
||||||
return callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers
|
|
||||||
*/
|
|
||||||
|
|
||||||
// URI Spec
|
|
||||||
// A backwards-compatible request:
|
|
||||||
// bitcoin:mq7se9wy2egettFxPbmn99cK8v5AFq55Lx?amount=0.11&r=https://merchant.com/pay.php?h%3D2a8628fc2fbe
|
|
||||||
// Non-backwards-compatible equivalent:
|
|
||||||
// bitcoin:?r=https://merchant.com/pay.php?h%3D2a8628fc2fbe
|
|
||||||
function parseMerchantURI(uri) {
|
|
||||||
uri = uri || 'bitcoin:?r=https://localhost:' + port + '/-/request';
|
|
||||||
var query, id;
|
|
||||||
if (uri.indexOf('bitcoin:') !== 0) {
|
|
||||||
throw new Error('Not a Bitcoin URI.');
|
|
||||||
}
|
|
||||||
if (~uri.indexOf(':?')) {
|
|
||||||
query = uri.split(':?')[1];
|
|
||||||
} else {
|
|
||||||
// Legacy URI
|
|
||||||
uri = uri.substring('bitcoin:'.length);
|
|
||||||
uri = uri.split('?');
|
|
||||||
id = uri[0];
|
|
||||||
query = uri[1];
|
|
||||||
}
|
|
||||||
query = parseQS(query);
|
|
||||||
if (!query.r) {
|
|
||||||
throw new Error('No uri.');
|
|
||||||
}
|
|
||||||
if (id) {
|
|
||||||
query.id = id;
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseQS(query) {
|
|
||||||
var out = {};
|
|
||||||
var parts = query.split('&');
|
|
||||||
parts.forEach(function(part) {
|
|
||||||
var parts = part.split('=');
|
|
||||||
var key = parts[0];
|
|
||||||
var value = parts[1];
|
|
||||||
out[key] = value;
|
|
||||||
});
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createTX(outputs) {
|
|
||||||
// Addresses
|
|
||||||
var addrs = [
|
|
||||||
'mzTQ66VKcybz9BD1LAqEwMFp9NrBGS82sY',
|
|
||||||
'mmu9k3KzsDMEm9JxmJmZaLhovAoRKW3zr4',
|
|
||||||
'myqss64GNZuWuFyg5LTaoTCyWEpKH56Fgz'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Private keys in WIF format (see TransactionBuilder.js for other options)
|
|
||||||
var keys = [
|
|
||||||
'cVvr5YmWVAkVeZWAawd2djwXM4QvNuwMdCw1vFQZBM1SPFrtE8W8',
|
|
||||||
'cPyx1hXbe3cGQcHZbW3GNSshCYZCriidQ7afR2EBsV6ReiYhSkNF'
|
|
||||||
// 'cUB9quDzq1Bj7pocenmofzNQnb1wJNZ5V3cua6pWKzNL1eQtaDqQ'
|
|
||||||
];
|
|
||||||
|
|
||||||
var unspent = [{
|
|
||||||
// http://blockexplorer.com/testnet/rawtx/1fcfe898cc2612f8b222bd3b4ac8d68bf95d43df8367b71978c184dea35bde22
|
|
||||||
'txid': '1fcfe898cc2612f8b222bd3b4ac8d68bf95d43df8367b71978c184dea35bde22',
|
|
||||||
'vout': 1,
|
|
||||||
'address': addrs[0],
|
|
||||||
'scriptPubKey': '76a94c14cfbe41f4a518edc25af71bafc72fb61bfcfc4fcd88ac',
|
|
||||||
'amount': 1.60000000,
|
|
||||||
'confirmations': 9
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
// http://blockexplorer.com/testnet/rawtx/0624c0c794447b0d2343ae3d20382983f41b915bb115a834419e679b2b13b804
|
|
||||||
'txid': '0624c0c794447b0d2343ae3d20382983f41b915bb115a834419e679b2b13b804',
|
|
||||||
'vout': 1,
|
|
||||||
'address': addrs[1],
|
|
||||||
'scriptPubKey': '76a94c14460376539c219c5e3274d86f16b40e806b37817688ac',
|
|
||||||
'amount': 1.60000000,
|
|
||||||
'confirmations': 9
|
|
||||||
}];
|
|
||||||
|
|
||||||
// set change address
|
|
||||||
var opts = {
|
|
||||||
remainderOut: {
|
|
||||||
address: addrs[0]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var outs = [];
|
|
||||||
outputs.forEach(function(output) {
|
|
||||||
var amount = output.get('amount');
|
|
||||||
var script = {
|
|
||||||
offset: output.get('script').offset,
|
|
||||||
limit: output.get('script').limit,
|
|
||||||
buffer: new Buffer(new Uint8Array(
|
|
||||||
output.get('script').buffer))
|
|
||||||
};
|
|
||||||
|
|
||||||
// big endian
|
|
||||||
var v = new Buffer(8);
|
|
||||||
v[0] = (amount.high >> 24) & 0xff;
|
|
||||||
v[1] = (amount.high >> 16) & 0xff;
|
|
||||||
v[2] = (amount.high >> 8) & 0xff;
|
|
||||||
v[3] = (amount.high >> 0) & 0xff;
|
|
||||||
v[4] = (amount.low >> 24) & 0xff;
|
|
||||||
v[5] = (amount.low >> 16) & 0xff;
|
|
||||||
v[6] = (amount.low >> 8) & 0xff;
|
|
||||||
v[7] = (amount.low >> 0) & 0xff;
|
|
||||||
|
|
||||||
var s = script.buffer.slice(script.offset, script.limit);
|
|
||||||
var addr = bitcore.Address.fromScriptPubKey(new bitcore.Script(s), 'testnet');
|
|
||||||
|
|
||||||
outs.push({
|
|
||||||
address: addr.toString(),
|
|
||||||
amountSatStr: bitcore.Bignum.fromBuffer(v, {
|
|
||||||
// XXX for some reason, endian is ALWAYS 'big'
|
|
||||||
// in node (in the browser it behaves correctly)
|
|
||||||
endian: 'big',
|
|
||||||
size: 1
|
|
||||||
}).toString(10)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var b = new bitcore.TransactionBuilder(opts)
|
|
||||||
.setUnspent(unspent)
|
|
||||||
.setOutputs(outs);
|
|
||||||
|
|
||||||
outputs.forEach(function(output, i) {
|
|
||||||
var script = {
|
|
||||||
offset: output.get('script').offset,
|
|
||||||
limit: output.get('script').limit,
|
|
||||||
buffer: new Buffer(new Uint8Array(
|
|
||||||
output.get('script').buffer))
|
|
||||||
};
|
|
||||||
var s = script.buffer.slice(script.offset, script.limit);
|
|
||||||
b.tx.outs[i].s = s;
|
|
||||||
});
|
|
||||||
|
|
||||||
b = b.sign(keys);
|
|
||||||
|
|
||||||
var tx = b.build();
|
|
||||||
|
|
||||||
print('');
|
|
||||||
print('Customer created transaction:');
|
|
||||||
print(tx.getStandardizedObject());
|
|
||||||
print('');
|
|
||||||
|
|
||||||
return tx.serialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers
|
|
||||||
*/
|
|
||||||
|
|
||||||
function clientLog(args, isError) {
|
|
||||||
var log = document.getElementById('log');
|
|
||||||
var msg = args[0];
|
|
||||||
if (typeof msg !== 'string') {
|
|
||||||
msg = JSON.stringify(msg, null, 2);
|
|
||||||
if (isError) msg = '<span style="color:red;">' + msg + '</span>';
|
|
||||||
log.innerHTML += msg + '\n';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var i = 0;
|
|
||||||
msg = msg.replace(/%[sdji]/g, function(ch) {
|
|
||||||
i++;
|
|
||||||
if (ch === 'j' || typeof args[i] !== 'string') {
|
|
||||||
return JSON.stringify(args[i]);
|
|
||||||
}
|
|
||||||
return args[i];
|
|
||||||
});
|
|
||||||
if (isError) msg = '<span style="color:red;">' + msg + '</span>';
|
|
||||||
log.innerHTML += msg + '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
function print() {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
if (!isNode) {
|
|
||||||
return clientLog(args, false);
|
|
||||||
}
|
|
||||||
var util = require('util');
|
|
||||||
if (typeof args[0] !== 'string') {
|
|
||||||
args[0] = util.inspect(args[0], null, 20, true);
|
|
||||||
console.log('\x1b[32mCustomer:\x1b[m');
|
|
||||||
console.log(args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!args[0]) return process.stdout.write('\n');
|
|
||||||
var msg = '\x1b[32mCustomer:\x1b[m '
|
|
||||||
+ util.format.apply(util.format, args);
|
|
||||||
return process.stdout.write(msg + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
function error() {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
if (!isNode) {
|
|
||||||
return clientLog(args, true);
|
|
||||||
}
|
|
||||||
var util = require('util');
|
|
||||||
if (typeof args[0] !== 'string') {
|
|
||||||
args[0] = util.inspect(args[0], null, 20, true);
|
|
||||||
console.log('\x1b[32mCustomer:\x1b[m');
|
|
||||||
console.log(args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!args[0]) return process.stderr.write('\n');
|
|
||||||
var msg = '\x1b[32mCustomer:\x1b[m \x1b[31m'
|
|
||||||
+ util.format.apply(util.format, args) + '\x1b[m';
|
|
||||||
return process.stderr.write(msg + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (isNode) {
|
|
||||||
if (!module.parent) {
|
|
||||||
sendPayment(function(err) {
|
|
||||||
if (err) return error(err.message);
|
|
||||||
print('Payment sent successfully.');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var customer = sendPayment;
|
|
||||||
customer.sendPayment = sendPayment;
|
|
||||||
customer.print = print;
|
|
||||||
customer.error = error;
|
|
||||||
module.exports = customer;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var customer = sendPayment;
|
|
||||||
customer.sendPayment = sendPayment;
|
|
||||||
customer.print = print;
|
|
||||||
customer.error = error;
|
|
||||||
window.customer = window.sendPayment = customer;
|
|
||||||
window.onload = function() {
|
|
||||||
var form = document.getElementsByTagName('form')[0];
|
|
||||||
var memo = document.querySelector('input[name="memo"]');
|
|
||||||
var loader = document.getElementById('load');
|
|
||||||
loader.style.display = 'none';
|
|
||||||
form.onsubmit = function() {
|
|
||||||
form.style.display = 'none';
|
|
||||||
loader.style.display = 'block';
|
|
||||||
form.onsubmit = function() { return false; };
|
|
||||||
customer.sendPayment(memo.value || null, function(err) {
|
|
||||||
loader.style.display = 'none';
|
|
||||||
if (err) return error(err.message);
|
|
||||||
print('Payment sent successfully.');
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}).call(function() {
|
|
||||||
return this || (typeof window !== 'undefined' ? window : global);
|
|
||||||
}());
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<title>Payment Protocol</title>
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
|
||||||
|
|
||||||
<h1>Payment Protocol</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki"><strong>BIP-70</strong></a>
|
|
||||||
is here!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form method="POST" action="/-/request">
|
|
||||||
<ul>
|
|
||||||
<li>BitPay T-Shirt: <strong>0.00002000 BTC</strong></li>
|
|
||||||
<li>BitPay Mug: <strong>0.00001000 BTC</strong></li>
|
|
||||||
</ul>
|
|
||||||
<p>These items will cost you a total of <strong>0.00003000 BTC</strong>.</p>
|
|
||||||
<p>Would you like to checkout?</p>
|
|
||||||
<input type="text" name="memo" placeholder="Message to merchant..." value="">
|
|
||||||
<input type="submit" value="Checkout">
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p id="load">Loading...</p>
|
|
||||||
|
|
||||||
<pre id="log"></pre>
|
|
||||||
|
|
||||||
<script src="./bitcore.js"></script>
|
|
||||||
<script src="./customer.js"></script>
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
module.exports = require('./server');
|
|
||||||
@ -1,438 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Payment-Server - A Payment Protocol demonstration.
|
|
||||||
* Copyright (c) 2014, BitPay
|
|
||||||
* https://github.com/bitpay/bitcore
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modules
|
|
||||||
*/
|
|
||||||
|
|
||||||
var https = require('https');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
var qs = require('querystring');
|
|
||||||
var crypto = require('crypto');
|
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
// Disable strictSSL
|
|
||||||
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dependencies
|
|
||||||
*/
|
|
||||||
|
|
||||||
var argv = require('optimist').argv;
|
|
||||||
var express = require('express');
|
|
||||||
var bitcore = require('../../');
|
|
||||||
|
|
||||||
var PayPro = bitcore.PayPro;
|
|
||||||
var Transaction = bitcore.Transaction;
|
|
||||||
var TransactionBuilder = bitcore.TransactionBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variables
|
|
||||||
*/
|
|
||||||
|
|
||||||
var x509 = {
|
|
||||||
priv: fs.readFileSync(__dirname + '/../../test/data/x509.key'),
|
|
||||||
pub: fs.readFileSync(__dirname + '/../../test/data/x509.pub'),
|
|
||||||
der: fs.readFileSync(__dirname + '/../../test/data/x509.der'),
|
|
||||||
pem: fs.readFileSync(__dirname + '/../../test/data/x509.crt')
|
|
||||||
};
|
|
||||||
|
|
||||||
var server = https.createServer({
|
|
||||||
key: fs.readFileSync(__dirname + '/../../test/data/x509.key'),
|
|
||||||
cert: fs.readFileSync(__dirname + '/../../test/data/x509.crt')
|
|
||||||
});
|
|
||||||
|
|
||||||
server.options = argv;
|
|
||||||
|
|
||||||
server.setOptions = function(options) {
|
|
||||||
server.options = argv = options;
|
|
||||||
};
|
|
||||||
|
|
||||||
var app = express();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ignore Cache Headers
|
|
||||||
* Allow CORS
|
|
||||||
* Accept Payments
|
|
||||||
*/
|
|
||||||
|
|
||||||
app.use(function(req, res, next) {
|
|
||||||
var setHeader = res.setHeader;
|
|
||||||
|
|
||||||
res.setHeader = function(name) {
|
|
||||||
switch (name) {
|
|
||||||
case 'Cache-Control':
|
|
||||||
case 'Last-Modified':
|
|
||||||
case 'ETag':
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return setHeader.apply(res, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
||||||
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
|
|
||||||
res.setHeader('Access-Control-Allow-Headers', [
|
|
||||||
'Host',
|
|
||||||
'Connection',
|
|
||||||
'Content-Length',
|
|
||||||
'Accept',
|
|
||||||
'Origin',
|
|
||||||
'User-Agent',
|
|
||||||
'Content-Type',
|
|
||||||
'Accept-Encoding',
|
|
||||||
'Accept-Language'
|
|
||||||
].join(','));
|
|
||||||
|
|
||||||
res.setHeader('Accept', PayPro.PAYMENT_CONTENT_TYPE);
|
|
||||||
|
|
||||||
return next();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Body Parser
|
|
||||||
*/
|
|
||||||
|
|
||||||
app.use('/-/pay', function(req, res, next) {
|
|
||||||
var buf = [];
|
|
||||||
|
|
||||||
req.on('error', function(err) {
|
|
||||||
error('Request Error: %s', err.message);
|
|
||||||
try {
|
|
||||||
req.socket.destroy();
|
|
||||||
} catch (e) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('data', function(data) {
|
|
||||||
buf.push(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('end', function(data) {
|
|
||||||
if (data) buf.push(data);
|
|
||||||
buf = Buffer.concat(buf, buf.length);
|
|
||||||
req.paymentData = buf;
|
|
||||||
return next();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Router
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Not used in express 4.x
|
|
||||||
// app.use(app.router);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive "I want to pay"
|
|
||||||
*/
|
|
||||||
|
|
||||||
app.uid = 0;
|
|
||||||
|
|
||||||
app.get('/-/request', function(req, res, next) {
|
|
||||||
print('Received payment "request" from %s.', req.socket.remoteAddress);
|
|
||||||
|
|
||||||
var outputs = [];
|
|
||||||
|
|
||||||
[2000, 1000, 10000].forEach(function(value) {
|
|
||||||
var po = new PayPro();
|
|
||||||
po = po.makeOutput();
|
|
||||||
|
|
||||||
// number of satoshis to be paid
|
|
||||||
po.set('amount', value);
|
|
||||||
|
|
||||||
// a TxOut script where the payment should be sent. similar to OP_CHECKSIG
|
|
||||||
|
|
||||||
// Instead of creating it ourselves:
|
|
||||||
// if (!argv.pubkey && !argv.privkey && !argv.address) {
|
|
||||||
// //argv.pubkey = '3730febcba04bad0cd476cfb820f9c37d7466fd9';
|
|
||||||
// argv.pubkey = 'd96f46d7379c0f82fb6c47cdd0ba04babcfe3037'
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (argv.pubkey || argv.privkey || argv.address) {
|
|
||||||
var pubKey;
|
|
||||||
if (argv.pubkey) {
|
|
||||||
pubKey = new Buffer(argv.pubkey, 'hex');
|
|
||||||
} else if (argv.privkey) {
|
|
||||||
pubKey = bitcore.Key.recoverPubKey(new Buffer(argv.privkey)).toCompressedPubKey();
|
|
||||||
} else if (argv.address) {
|
|
||||||
pubKey = bitcore.Base58Check.decode(new Buffer(argv.address));
|
|
||||||
}
|
|
||||||
var address = bitcore.Address.fromPubKey(pubKey, 'testnet');
|
|
||||||
var scriptPubKey = address.getScriptPubKey();
|
|
||||||
assert.equal(scriptPubKey.isPubkeyHash(), true);
|
|
||||||
po.set('script', scriptPubKey.getBuffer());
|
|
||||||
} else {
|
|
||||||
po.set('script', new Buffer([
|
|
||||||
118, // OP_DUP
|
|
||||||
169, // OP_HASH160
|
|
||||||
76, // OP_PUSHDATA1
|
|
||||||
20, // number of bytes
|
|
||||||
55,
|
|
||||||
48,
|
|
||||||
254,
|
|
||||||
188,
|
|
||||||
186,
|
|
||||||
4,
|
|
||||||
186,
|
|
||||||
208,
|
|
||||||
205,
|
|
||||||
71,
|
|
||||||
108,
|
|
||||||
251,
|
|
||||||
130,
|
|
||||||
15,
|
|
||||||
156,
|
|
||||||
55,
|
|
||||||
215,
|
|
||||||
70,
|
|
||||||
111,
|
|
||||||
217,
|
|
||||||
136, // OP_EQUALVERIFY
|
|
||||||
172 // OP_CHECKSIG
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
|
|
||||||
outputs.push(po.message);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Payment Details
|
|
||||||
*/
|
|
||||||
|
|
||||||
var mdata = new Buffer([0]);
|
|
||||||
app.uid++;
|
|
||||||
if (app.uid > 0xffff) {
|
|
||||||
throw new Error('UIDs bigger than 0xffff not supported.');
|
|
||||||
} else if (app.uid > 0xff) {
|
|
||||||
mdata = new Buffer([(app.uid >> 8) & 0xff, (app.uid >> 0) & 0xff])
|
|
||||||
} else {
|
|
||||||
mdata = new Buffer([0, app.uid])
|
|
||||||
}
|
|
||||||
var now = Date.now() / 1000 | 0;
|
|
||||||
var pd = new PayPro();
|
|
||||||
pd = pd.makePaymentDetails();
|
|
||||||
pd.set('network', 'test');
|
|
||||||
pd.set('outputs', outputs);
|
|
||||||
pd.set('time', now);
|
|
||||||
pd.set('expires', now + 60 * 60 * 24);
|
|
||||||
pd.set('memo', 'Hello, this is the server, we would like some money.');
|
|
||||||
var port = +req.headers.host.split(':')[1] || server.port;
|
|
||||||
pd.set('payment_url', 'https://localhost:' + port + '/-/pay');
|
|
||||||
pd.set('merchant_data', mdata);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PaymentRequest
|
|
||||||
*/
|
|
||||||
|
|
||||||
var cr = new PayPro();
|
|
||||||
cr = cr.makeX509Certificates();
|
|
||||||
cr.set('certificate', [x509.der]);
|
|
||||||
|
|
||||||
// We send the PaymentRequest to the customer
|
|
||||||
var pr = new PayPro();
|
|
||||||
pr = pr.makePaymentRequest();
|
|
||||||
pr.set('payment_details_version', 1);
|
|
||||||
pr.set('pki_type', 'x509+sha256');
|
|
||||||
pr.set('pki_data', cr.serialize());
|
|
||||||
pr.set('serialized_payment_details', pd.serialize());
|
|
||||||
pr.sign(x509.priv);
|
|
||||||
|
|
||||||
pr = pr.serialize();
|
|
||||||
|
|
||||||
// BIP-71 - set the content-type
|
|
||||||
res.setHeader('Content-Type', PayPro.PAYMENT_REQUEST_CONTENT_TYPE);
|
|
||||||
res.setHeader('Content-Length', pr.length + '');
|
|
||||||
res.setHeader('Content-Transfer-Encoding', 'binary');
|
|
||||||
|
|
||||||
res.send(pr);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive Payment
|
|
||||||
*/
|
|
||||||
|
|
||||||
app.post('/-/pay', function(req, res, next) {
|
|
||||||
var body = req.paymentData;
|
|
||||||
|
|
||||||
print('Received Payment Message Body:');
|
|
||||||
print(body.toString('hex'));
|
|
||||||
|
|
||||||
body = PayPro.Payment.decode(body);
|
|
||||||
|
|
||||||
var pay = new PayPro();
|
|
||||||
pay = pay.makePayment(body);
|
|
||||||
var merchant_data = pay.get('merchant_data');
|
|
||||||
var transactions = pay.get('transactions');
|
|
||||||
var refund_to = pay.get('refund_to');
|
|
||||||
var memo = pay.get('memo');
|
|
||||||
|
|
||||||
print('Received Payment from %s.', req.socket.remoteAddress);
|
|
||||||
print('Customer Message: %s', memo);
|
|
||||||
print('Payment Message:');
|
|
||||||
print(pay);
|
|
||||||
|
|
||||||
// We send this to the customer after receiving a Payment
|
|
||||||
// Then we propogate the transaction through bitcoin network
|
|
||||||
var ack = new PayPro();
|
|
||||||
ack = ack.makePaymentACK();
|
|
||||||
ack.set('payment', pay.message);
|
|
||||||
ack.set('memo', 'Thank you for your payment!');
|
|
||||||
|
|
||||||
ack = ack.serialize();
|
|
||||||
|
|
||||||
// BIP-71 - set the content-type
|
|
||||||
res.setHeader('Content-Type', PayPro.PAYMENT_ACK_CONTENT_TYPE);
|
|
||||||
res.setHeader('Content-Length', ack.length + '');
|
|
||||||
res.setHeader('Content-Transfer-Encoding', 'binary');
|
|
||||||
|
|
||||||
transactions = transactions.map(function(tx) {
|
|
||||||
tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
|
|
||||||
var ptx = new bitcore.Transaction();
|
|
||||||
ptx.parse(tx.buffer);
|
|
||||||
return ptx;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!argv['no-tx']) {
|
|
||||||
(function retry() {
|
|
||||||
var timeout = setTimeout(function() {
|
|
||||||
if (conn) {
|
|
||||||
transactions.forEach(function(tx) {
|
|
||||||
var id = tx.getHash().toString('hex');
|
|
||||||
print('');
|
|
||||||
print('Sending transaction with txid: %s', id);
|
|
||||||
print(tx.getStandardizedObject());
|
|
||||||
|
|
||||||
print('Broadcasting transaction...');
|
|
||||||
|
|
||||||
var pending = 1;
|
|
||||||
peerman.on('ack', function listener() {
|
|
||||||
if (!--pending) {
|
|
||||||
peerman.removeListener('ack', listener);
|
|
||||||
clearTimeout(timeout);
|
|
||||||
print('Transaction sent to peer successfully.');
|
|
||||||
res.send(ack);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
conn.sendTx(tx);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
print('No BTC network connection. Retrying...');
|
|
||||||
conn = peerman.getActiveConnection();
|
|
||||||
retry();
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
})();
|
|
||||||
} else {
|
|
||||||
print('Broadcasting transaction...');
|
|
||||||
res.send(ack);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bitcoin
|
|
||||||
*/
|
|
||||||
|
|
||||||
var conn;
|
|
||||||
|
|
||||||
var peerman = new bitcore.PeerManager({
|
|
||||||
network: 'testnet'
|
|
||||||
});
|
|
||||||
|
|
||||||
peerman.peerDiscovery = argv.d || argv.discovery || false;
|
|
||||||
|
|
||||||
peerman.addPeer(new bitcore.Peer('testnet-seed.alexykot.me', 18333));
|
|
||||||
peerman.addPeer(new bitcore.Peer('testnet-seed.bitcoin.petertodd.org', 18333));
|
|
||||||
peerman.addPeer(new bitcore.Peer('testnet-seed.bluematt.me', 18333));
|
|
||||||
|
|
||||||
peerman.on('connect', function() {
|
|
||||||
conn = peerman.getActiveConnection();
|
|
||||||
});
|
|
||||||
|
|
||||||
peerman.start();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File Access
|
|
||||||
*/
|
|
||||||
|
|
||||||
app.use(express.static(__dirname));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers
|
|
||||||
*/
|
|
||||||
|
|
||||||
var log = require('../../util/log');
|
|
||||||
|
|
||||||
log.err = error;
|
|
||||||
log.debug = error;
|
|
||||||
log.info = print;
|
|
||||||
|
|
||||||
var util = require('util');
|
|
||||||
|
|
||||||
function print() {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
if (typeof args[0] !== 'string') {
|
|
||||||
args[0] = util.inspect(args[0], null, 20, true);
|
|
||||||
console.log('\x1b[34mServer:\x1b[m');
|
|
||||||
console.log(args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!args[0]) return process.stdout.write('\n');
|
|
||||||
var msg = '\x1b[34mServer:\x1b[m '
|
|
||||||
+ util.format.apply(util.format, args);
|
|
||||||
return process.stdout.write(msg + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
function error() {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
if (typeof args[0] !== 'string') {
|
|
||||||
args[0] = util.inspect(args[0], null, 20, true);
|
|
||||||
console.log('\x1b[34mServer:\x1b[m');
|
|
||||||
console.log(args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!args[0]) return process.stderr.write('\n');
|
|
||||||
var msg = '\x1b[34mServer:\x1b[m \x1b[31m'
|
|
||||||
+ util.format.apply(util.format, args)
|
|
||||||
+ '\x1b[m';
|
|
||||||
return process.stderr.write(msg + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start Server
|
|
||||||
*/
|
|
||||||
|
|
||||||
server.on('request', app);
|
|
||||||
server.app = app;
|
|
||||||
server.port = 8080;
|
|
||||||
server.isNode = true;
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
server.port = argv.p = argv.port = +argv.p || +argv.port || 8080;
|
|
||||||
server.isNode = !argv.b && !argv.browser;
|
|
||||||
if (argv.s || argv.server || argv.l || argv.listen) {
|
|
||||||
server.listen(server.port, function(addr) {
|
|
||||||
print('Listening on port %s.', server.port);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!module.parent || path.basename(module.parent.filename) === 'index.js') {
|
|
||||||
server.listen(server.port, function(addr) {
|
|
||||||
print('Listening on port %s.', server.port);
|
|
||||||
if (!server.isNode) return;
|
|
||||||
var customer = require('./customer');
|
|
||||||
customer.sendPayment(function(err) {
|
|
||||||
if (err) return error(err.message);
|
|
||||||
customer.print('Payment sent successfully.');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 1);
|
|
||||||
|
|
||||||
module.exports = server;
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* Stylesheet for Payment Protocol
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Raleway
|
|
||||||
*/
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Raleway';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Raleway'), url(http://themes.googleusercontent.com/static/fonts/raleway/v7/cIFypx4yrWPDz3zOxk7hIQLUuEpTyoUstqEm5AMlJo4.woff) format('woff');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ubuntu
|
|
||||||
*/
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Ubuntu';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Ubuntu'), url(https://themes.googleusercontent.com/static/fonts/ubuntu/v5/lhhB5ZCwEkBRbHMSnYuKyA.ttf) format('truetype');
|
|
||||||
}
|
|
||||||
|
|
||||||
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary {
|
|
||||||
display: block
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
width: 840px;
|
|
||||||
font-family: "Raleway", "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Helvetica", "Verdana", sans-serif;
|
|
||||||
font-size: 22px;
|
|
||||||
line-height: 30px;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
color: #000;
|
|
||||||
background-image: -webkit-gradient( linear, 0 0, 0 100%, color-stop(0, rgba(0, 0, 0, 0.15)), color-stop(0.2, transparent), color-stop(0.8, transparent), color-stop(1, rgba(0, 0, 0, 0.15)));
|
|
||||||
background-image: -moz-linear-gradient( -90deg, rgba(0, 0, 0, 0.15) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.15) 100%);
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-color: #c1d3e3;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
display: block;
|
|
||||||
margin: 0 0 20px 0;
|
|
||||||
font-family: "Raleway", "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Helvetica", "Verdana", sans-serif;
|
|
||||||
font-size: 22px;
|
|
||||||
line-height: 30px;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding: 20px;
|
|
||||||
text-shadow: rgba(0, 0, 0, 0.025) 0 -1px 0, rgba(255, 255, 255, 0.2) 0 1px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
width: 350px;
|
|
||||||
color: #000;
|
|
||||||
font: 60px/1.0 "Ubuntu", "Helvetica", "Verdana", "Arial", sans-serif;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
var bitcore = require('../bitcore');
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var bitcoreUtil = bitcore.util;
|
|
||||||
var Script = bitcore.Script;
|
|
||||||
var network = bitcore.networks.livenet;
|
|
||||||
|
|
||||||
|
|
||||||
var script = ''; // write down your script here
|
|
||||||
var s = Script.fromHumanReadable(script);
|
|
||||||
var hash = bitcoreUtil.sha256ripe160(s.getBuffer());
|
|
||||||
var version = network.addressScript;
|
|
||||||
|
|
||||||
var addr = new Address(version, hash);
|
|
||||||
var addrStr = addr.as('base58');
|
|
||||||
|
|
||||||
// This outputs the "address" of thescript
|
|
||||||
console.log(addrStr);
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
var PeerManager = require('../lib/PeerManager');
|
|
||||||
var peerman = new PeerManager();
|
|
||||||
|
|
||||||
peerman.discover({
|
|
||||||
limit: 12
|
|
||||||
}).start();
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var Peer = bitcore.Peer;
|
|
||||||
var PeerManager = bitcore.PeerManager;
|
|
||||||
|
|
||||||
var handleBlock = function(info) {
|
|
||||||
console.log('** Block Received **');
|
|
||||||
console.log(info.message);
|
|
||||||
};
|
|
||||||
|
|
||||||
var handleTx = function(info) {
|
|
||||||
var tx = info.message.tx.getStandardizedObject();
|
|
||||||
|
|
||||||
console.log('** TX Received **');
|
|
||||||
console.log(tx);
|
|
||||||
};
|
|
||||||
|
|
||||||
var handleInv = function(info) {
|
|
||||||
console.log('** Inv **');
|
|
||||||
console.log(info.message);
|
|
||||||
|
|
||||||
var invs = info.message.invs;
|
|
||||||
info.conn.sendGetData(invs);
|
|
||||||
};
|
|
||||||
|
|
||||||
var peerman = new PeerManager({
|
|
||||||
network: 'testnet'
|
|
||||||
});
|
|
||||||
|
|
||||||
peerman.addPeer(new Peer('127.0.0.1', 18333));
|
|
||||||
|
|
||||||
peerman.on('connection', function(conn) {
|
|
||||||
conn.on('inv', handleInv);
|
|
||||||
conn.on('block', handleBlock);
|
|
||||||
conn.on('tx', handleTx);
|
|
||||||
});
|
|
||||||
|
|
||||||
peerman.start();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var RpcClient = bitcore.RpcClient;
|
|
||||||
var hash = '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4';
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
protocol: 'http',
|
|
||||||
user: 'user',
|
|
||||||
pass: 'pass',
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: '18332',
|
|
||||||
};
|
|
||||||
|
|
||||||
var rpc = new RpcClient(config);
|
|
||||||
|
|
||||||
rpc.getBlock(hash, function(err, ret) {
|
|
||||||
if (err) {
|
|
||||||
console.error('An error occured fetching block', hash);
|
|
||||||
console.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(ret);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var coinUtil = bitcore.util;
|
|
||||||
var Script = bitcore.Script;
|
|
||||||
var network = bitcore.networks.testnet;
|
|
||||||
|
|
||||||
var getAddrStr = function(s) {
|
|
||||||
var addrStrs = [];
|
|
||||||
var type = s.classify();
|
|
||||||
var addr;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case Script.TX_PUBKEY:
|
|
||||||
var chunk = s.captureOne();
|
|
||||||
addr = new Address(network.addressVersion, coinUtil.sha256ripe160(chunk));
|
|
||||||
addrStrs.push(addr.toString());
|
|
||||||
break;
|
|
||||||
case Script.TX_PUBKEYHASH:
|
|
||||||
addr = new Address(network.addressVersion, s.captureOne());
|
|
||||||
addrStrs.push(addr.toString());
|
|
||||||
break;
|
|
||||||
case Script.TX_SCRIPTHASH:
|
|
||||||
addr = new Address(network.P2SHVersion, s.captureOne());
|
|
||||||
addrStrs.push(addr.toString());
|
|
||||||
break;
|
|
||||||
case Script.TX_MULTISIG:
|
|
||||||
var chunks = s.capture();
|
|
||||||
chunks.forEach(function(chunk) {
|
|
||||||
var a = new Address(network.addressVersion, coinUtil.sha256ripe160(chunk));
|
|
||||||
addrStrs.push(a.toString());
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case Script.TX_UNKNOWN:
|
|
||||||
console.log('tx type unkown');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return addrStrs;
|
|
||||||
};
|
|
||||||
|
|
||||||
var script = 'DUP HASH160 0x14 0x3744841e13b90b4aca16fe793a7f88da3a23cc71 EQUALVERIFY CHECKSIG';
|
|
||||||
var s = Script.fromHumanReadable(script);
|
|
||||||
console.log(getAddrStr(s)[0]); // mkZBYBiq6DNoQEKakpMJegyDbw2YiNQnHT
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var coinUtil = bitcore.util;
|
|
||||||
var Script = bitcore.Script;
|
|
||||||
var ScriptInterpreter = bitcore.ScriptInterpreter;
|
|
||||||
var network = bitcore.networks.testnet;
|
|
||||||
|
|
||||||
|
|
||||||
// using "static" method
|
|
||||||
var scriptPubKeyHR = '0x14 0x3744841e13b90b4aca16fe793a7f88da3a23cc71 EQUAL';
|
|
||||||
var scriptPubKey = Script.fromHumanReadable(scriptPubKeyHR);
|
|
||||||
|
|
||||||
var scriptSigHR = '0x14 0x3744841e13b90b4aca16fe793a7f88da3a23cc71';
|
|
||||||
var scriptSig = Script.fromHumanReadable(scriptSigHR);
|
|
||||||
|
|
||||||
ScriptInterpreter.verifyFull(scriptSig, scriptPubKey, undefined, undefined,
|
|
||||||
undefined, undefined, function(err, result) {
|
|
||||||
console.log('script verified successfully? ', result)
|
|
||||||
});
|
|
||||||
|
|
||||||
// using an instance
|
|
||||||
scriptPubKeyHR = '0x26 0x554e5a49500370e53982a1d5201829562c5d9eebf256eb755b92c9b1449afd99f9f8c3265631 DROP HASH256 0x20 0x34b4f6042e1bcfc6182ee2727a3d0069a9071385bc07b318f57e77a28ffa13ac EQUAL';
|
|
||||||
scriptPubKey = Script.fromHumanReadable(scriptPubKeyHR);
|
|
||||||
|
|
||||||
scriptSigHR = '0x41 0x0470e53982a1d5201829562c5d9eebf256eb755b92c9b1449afd99f9f8c3265631142f3bf6954e3bec4bdad1a1a197bf90904a1e6f06c209eb477e2fde00d26691';
|
|
||||||
scriptSig = Script.fromHumanReadable(scriptSigHR);
|
|
||||||
|
|
||||||
var si = new ScriptInterpreter();
|
|
||||||
si.verifyFull(scriptSig, scriptPubKey, undefined, undefined,
|
|
||||||
undefined, function(err, result) {
|
|
||||||
console.log('script verified successfully? ', result)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
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 = [{
|
|
||||||
'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 = [
|
|
||||||
'cQA75LXhV5JkMT8wkkqjR87SnHK4doh3c21p7PAd5tp8tc1tRBAY',
|
|
||||||
'cRz85dz9AiDieRpEwoucfXXQa1jdHHghcv6YnnVVGZ3MQyR1X4u2',
|
|
||||||
'cSq7yo4fvsbMyWVN945VUGUWMaSazZPWqBVJZyoGsHmNq6W4HVBV',
|
|
||||||
'cPa87VgwZfowGZYaEenoQeJgRfKW6PhZ1R65EHTkN1K19cSvc92G',
|
|
||||||
'cPQ9DSbBRLva9av5nqeF5AGrh3dsdW8p2E5jS4P8bDWZAoQTeeKB'
|
|
||||||
];
|
|
||||||
|
|
||||||
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) {
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
peerman.start();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
/**
|
|
||||||
* This is a simple script that will display network messages.
|
|
||||||
* It users the Peer / Connection classes directly instead of
|
|
||||||
* relying on PeerManager.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// replace by require('bitcore') if you use somewhere else
|
|
||||||
var bitcore = require('../');
|
|
||||||
|
|
||||||
//bitcore.config.logger = 'debug';
|
|
||||||
|
|
||||||
var Peer = bitcore.Peer,
|
|
||||||
Connection = bitcore.Connection;
|
|
||||||
|
|
||||||
var peer = new Peer('127.0.0.1', 8333);
|
|
||||||
|
|
||||||
var socket = peer.createConnection();
|
|
||||||
|
|
||||||
var con = new Connection(socket, peer);
|
|
||||||
|
|
||||||
con.on('error', function(msg) {
|
|
||||||
var peer = msg.peer,
|
|
||||||
err = msg.err;
|
|
||||||
console.error('Error connecting to peer', peer.host + ':' + peer.port, '(' + err.message + ')');
|
|
||||||
});
|
|
||||||
|
|
||||||
con.on('disconnect', function(msg) {
|
|
||||||
console.log('disconnect: ', msg);
|
|
||||||
});
|
|
||||||
|
|
||||||
con.on('connect', function(msg) {
|
|
||||||
console.log('Connected to %s', msg.peer.host + ':' + msg.peer.port);
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Listen P2P messages */
|
|
||||||
|
|
||||||
// Make a log function available to all listeners
|
|
||||||
// The log function is just like console.log except it prefixes
|
|
||||||
// messages with [host:port]
|
|
||||||
function listen(event_name, fn) {
|
|
||||||
con.on(event_name, function(event) {
|
|
||||||
fn(event, function() {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
var str = args.shift();
|
|
||||||
str = '[%s:%s] ' + str;
|
|
||||||
args = [str, event.peer.host, event.peer.port].concat(args);
|
|
||||||
console.log.apply(console, args);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
listen('getaddr', function(event, log) {
|
|
||||||
log('Received message getaddr');
|
|
||||||
log(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
listen('verack', function(event, log) {
|
|
||||||
log('Received message verack');
|
|
||||||
});
|
|
||||||
|
|
||||||
listen('version', function(event, log) {
|
|
||||||
log('Received message version (%s)', event.message.version);
|
|
||||||
});
|
|
||||||
|
|
||||||
listen('addr', function(event, log) {
|
|
||||||
log('Received message addr (%s addresses)', event.message.addrs.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
listen('inv', function(event, log) {
|
|
||||||
log('Received message inv (%s invs)', event.message.count);
|
|
||||||
console.log(event.message.invs);
|
|
||||||
});
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
var run = function() {
|
|
||||||
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
|
|
||||||
var bitcore = require('../bitcore');
|
|
||||||
var Key = bitcore.Key;
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
|
|
||||||
// config your regular expression
|
|
||||||
var re = /[0-9]{6}$/; // ends in 6 digits
|
|
||||||
|
|
||||||
var a, k, m;
|
|
||||||
while (true) {
|
|
||||||
k = Key.generateSync();
|
|
||||||
a = Address.fromKey(k);
|
|
||||||
m = a.toString().match(re);
|
|
||||||
if (m) break;
|
|
||||||
}
|
|
||||||
console.log('Address: ' + a.toString());
|
|
||||||
console.log('Private Key: ' + k.private.toString('hex'));
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.run = run;
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Run `node browser/build.js -a` in the repository's root directory before using those examples.
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<style>
|
|
||||||
textarea {
|
|
||||||
width: 400px;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="../../browser/bundle.js"></script>
|
|
||||||
Enter you paper wallet seed:<br>
|
|
||||||
<textarea id="seed">aagh hjfj sihk ietj giik wwai awtd uodh hnji
|
|
||||||
soss uaku egod utai itos fijj ihgi jhau jtoo</textarea>
|
|
||||||
<br>
|
|
||||||
<input type="submit" onclick="updateResult()" value="Generate">
|
|
||||||
<div id="result"></div>
|
|
||||||
<pre id="console"></pre>
|
|
||||||
<script>
|
|
||||||
var bitcore = require('bitcore'),
|
|
||||||
Address = bitcore.Address,
|
|
||||||
Armory = bitcore.Armory;
|
|
||||||
|
|
||||||
var logs = document.getElementById('console');
|
|
||||||
function log (msg) {
|
|
||||||
logs.insertAdjacentHTML('beforeend', msg + '\n');
|
|
||||||
}
|
|
||||||
function clear_log () {
|
|
||||||
logs.innerHTML = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSeed() {
|
|
||||||
return document.getElementById('seed').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateResult () {
|
|
||||||
clear_log();
|
|
||||||
var seed = getSeed();
|
|
||||||
|
|
||||||
var a = Armory.fromSeed(seed);
|
|
||||||
log('Armory MPK: ');
|
|
||||||
log('');
|
|
||||||
log('');
|
|
||||||
log('<textarea>' + a.pubkey.toString('hex') + '' + a.chaincode.toString('hex') + '</textarea>');
|
|
||||||
log('');
|
|
||||||
log('');
|
|
||||||
log('Some wallet addresses:');
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
log(Address.fromPubKey(a.pubkey).as('base58'));
|
|
||||||
a = a.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateResult();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Bitcore browser examples</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<pre>
|
|
||||||
<div id='content'></div>
|
|
||||||
</pre>
|
|
||||||
<script src="../../browser/bundle.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var Address = require('bitcore').Address;
|
|
||||||
|
|
||||||
var print = function (s,s2,s3) {
|
|
||||||
var div = document.getElementById('content');
|
|
||||||
div.innerHTML += s + (s2||'') + (s3||'') + '<br />';
|
|
||||||
};
|
|
||||||
|
|
||||||
print('<hr> <h1>Address</h1>' );
|
|
||||||
var addrStrings = [
|
|
||||||
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
|
|
||||||
"1A1zP1eP5QGefi2DMPTfTL5SLmv7Dixxxx",
|
|
||||||
"A1zP1eP5QGefi2DMPTfTL5SLmv7Dixxxx",
|
|
||||||
"1600 Pennsylvania Ave NW",
|
|
||||||
].map(function(addr) {
|
|
||||||
return new Address(addr);
|
|
||||||
});
|
|
||||||
|
|
||||||
addrStrings.forEach(function(addr) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
addr.validate();
|
|
||||||
print(addr.data + ": is a valid address");
|
|
||||||
} catch(e) {
|
|
||||||
print(addr.data + ": is not a valid address.");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
print('<hr> <h1>Key</h1>' );
|
|
||||||
/*
|
|
||||||
Using bitcore root module
|
|
||||||
*/
|
|
||||||
var bitcore = require('bitcore');
|
|
||||||
var Key = bitcore.Key;
|
|
||||||
var k = bitcore.Key.generateSync();
|
|
||||||
k.private = new bitcore.Buffer('8d76eb9ddfa64fd29f4c541eac2b03ffdd1810dd19b01a10593fdb08f6be25f5','hex');
|
|
||||||
k.regenerateSync();
|
|
||||||
print ('Generate Key Pair:');
|
|
||||||
print ('Private:' + bitcore.buffertools.toHex(k.private));
|
|
||||||
print ('Public:' + bitcore.buffertools.toHex(k.public));
|
|
||||||
|
|
||||||
print('<hr> <h1>Util</h1>' );
|
|
||||||
var coinUtil = bitcore.util;
|
|
||||||
|
|
||||||
var pk = '03d95e184cce34c3cfa58e9a277a09a7c5ed1b2a8134ea1e52887bc66fa3f47071'
|
|
||||||
|
|
||||||
var pubKeyHash = coinUtil.sha256(pk);
|
|
||||||
print(bitcore.buffertools.toHex(pubKeyHash));
|
|
||||||
pubKeyHash = coinUtil.sha256ripe160(pk);
|
|
||||||
print(bitcore.buffertools.toHex(pubKeyHash));
|
|
||||||
|
|
||||||
|
|
||||||
var Buffer = bitcore.Buffer;
|
|
||||||
|
|
||||||
pubKeyHash = coinUtil.ripe160(new bitcore.Buffer('hola'));
|
|
||||||
print(bitcore.buffertools.toHex(pubKeyHash));
|
|
||||||
|
|
||||||
var bu = new Buffer('a5c756101065ac5b8f689139e6d856fa99e54b5000b6428b43729d334cc9277d', 'hex');
|
|
||||||
print(bitcore.buffertools.toHex(bu));
|
|
||||||
|
|
||||||
var pubKeyHash2 = coinUtil.ripe160(bu);
|
|
||||||
print(bitcore.buffertools.toHex(pubKeyHash2));
|
|
||||||
|
|
||||||
|
|
||||||
print('<hr><h1>WalletKey </h1>');
|
|
||||||
var WalletKey = bitcore.WalletKey;
|
|
||||||
var networks = bitcore.networks;
|
|
||||||
|
|
||||||
|
|
||||||
var priv = 'L4cEVwoNDeYdCQfFJAGkGKPnE2TmqLEuBn4znQChD2ojjQRJVKpU';
|
|
||||||
var s = new WalletKey({
|
|
||||||
network: networks.livenet
|
|
||||||
});
|
|
||||||
s.fromObj({ priv: priv});
|
|
||||||
var o = s.storeObj();
|
|
||||||
print("Private: " + o.priv);
|
|
||||||
print("Public: " + o.pub);
|
|
||||||
print("Addr: " + o.addr);
|
|
||||||
|
|
||||||
print('<hr><h1>TransactionBuilder</h1>');
|
|
||||||
console.log = print;
|
|
||||||
</script>
|
|
||||||
<script src="../CreateAndSignTx-PayToPubkeyHash.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<script src="../../browser/bundle.js"></script>
|
|
||||||
<pre id="console"></pre>
|
|
||||||
<script>
|
|
||||||
var bitcore = require('bitcore');
|
|
||||||
var Address = bitcore.Address;
|
|
||||||
var a = new Address('1KerhGhLn3SYBEQwby7VyVMWf16fXQUj5d');
|
|
||||||
document.getElementById('console').innerHTML = '1KerhGhLn3SYBEQwby7VyVMWf16fXQUj5d is valid? '+a.isValid();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loading…
Reference in New Issue
Block a user