From c8ebf0ce656f64b26b73854fafe4fdfe0af7356b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 21 May 2014 11:10:19 -0300 Subject: [PATCH 1/4] working on find_m_n script --- js/controllers/send.js | 3 +- js/models/core/Wallet.js | 5 ++- js/models/core/WalletFactory.js | 5 ++- test/find_m_n.js | 65 +++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100755 test/find_m_n.js diff --git a/js/controllers/send.js b/js/controllers/send.js index 07bbfbb53..5a78389cc 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -52,8 +52,7 @@ angular.module('copay.send').controller('SendController', var amount = (form.amount.$modelValue * 100000000).toString(); // satoshi to string var w = $rootScope.wallet; - w.createTx( address, amount,function() { - + w.createTx(address, amount,function() { $scope.loading = false; $rootScope.$flashMessage = { message: 'The transaction proposal has been created', type: 'success'}; $rootScope.$digest(); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 58008ae79..42c754037 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -20,7 +20,8 @@ function Wallet(opts) { 'requiredCopayers', 'totalCopayers', 'spendUnconfirmed', 'publicKeyRing', 'txProposals', 'privateKey', 'version' ].forEach(function(k) { - if (typeof opts[k] === 'undefined') throw new Error('missing key:' + k); + if (typeof opts[k] === 'undefined') + throw new Error('missing required option for Wallet: ' + k); self[k] = opts[k]; }); @@ -544,6 +545,8 @@ Wallet.prototype.getUnspent = function(cb) { Wallet.prototype.createTx = function(toAddress, amountSatStr, opts, cb) { var self = this; + alert(amountSatStr); + alert(JSON.stringify(opts)); if (typeof opts === 'function') { cb = opts; opts = {}; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index fc7f0ee77..602d8c3a2 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -17,6 +17,8 @@ var Wallet = require('./Wallet'); function WalletFactory(config, version) { var self = this; + config = config || {}; + this.storage = new Storage(config.storage); this.network = new Network(config.network); this.blockchain = new Blockchain(config.blockchain); @@ -97,7 +99,6 @@ WalletFactory.prototype.create = function(opts) { opts.privateKey = opts.privateKey || new PrivateKey({ networkName: this.networkName }); - var requiredCopayers = opts.requiredCopayers || this.walletDefaults.requiredCopayers; var totalCopayers = opts.totalCopayers || this.walletDefaults.totalCopayers; @@ -124,7 +125,7 @@ WalletFactory.prototype.create = function(opts) { opts.spendUnconfirmed = opts.spendUnconfirmed || this.walletDefaults.spendUnconfirmed; opts.requiredCopayers = requiredCopayers; opts.totalCopayers = totalCopayers; - opts.version = this.version; + opts.version = opts.version || this.version; var w = new Wallet(opts); w.store(); return w; diff --git a/test/find_m_n.js b/test/find_m_n.js new file mode 100755 index 000000000..678a3d5dd --- /dev/null +++ b/test/find_m_n.js @@ -0,0 +1,65 @@ +#!/usr/bin/env node + +'use strict'; + +var bitcore = require('bitcore'); +var PublicKeyRing = require('../js/models/core/PublicKeyRing'); +var PrivateKey = require('../js/models/core/PrivateKey'); + +var FakeNetwork = require('./mocks/FakeNetwork'); +var Insight = require('../js/models/blockchain/Insight'); +var FakeStorage = require('./mocks/FakeStorage'); + +var WalletFactory = require('soop').load('../js/models/core/WalletFactory', { + Network: FakeNetwork, + Blockchain: Insight, + Storage: FakeStorage, +}); +var Key = bitcore.Key; + + +var N_LIMIT = 16; +var nn = 'livenet'; + +for (var n = 1; n < N_LIMIT; n++) { + for (var m = 1; m <= n; m++) { + // case m-of-n + console.log('case '+m+'-of-'+n); + // create full pkr + var publicKeyRing = new PublicKeyRing({ + networkName: nn, + requiredCopayers: m, + totalCopayers: n, + }); + var privateKey = null; + for (var i = 0; i < n; i++) { + var pk = new PrivateKey({ + networkName: nn + }); + if (i === 0) { + privateKey = pk; + } else { + publicKeyRing.addCopayer(pk.getExtendedPublicKeyString(), 'dummy'); + } + } + + var opts = {}; + opts.publicKeyRing = publicKeyRing; + opts.privateKey = privateKey; + opts.requiredCopayers = m; + opts.totalCopayers = n; + opts.spendUnconfirmed = true; + opts.version = 'script' + + var w = new WalletFactory(opts).create(opts); + var addr = w.generateAddress(); + console.log('\t receive addr='+addr); + + + var toAddress = 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'; + var amount = '5000000'; + + + + } +} From 73e7d2a8275f7341461ed741a1d593e440b68eba Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 21 May 2014 15:14:48 -0300 Subject: [PATCH 2/4] advancing with m-n script --- js/models/core/Wallet.js | 7 ++----- package.json | 3 ++- test/find_m_n.js | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 42c754037..442c44449 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -440,9 +440,8 @@ Wallet.prototype.sendTx = function(ntxid, cb) { this.log('[Wallet.js.261:txHex:]', txHex); //TODO var self = this; - this.blockchain.sendRawTransaction(txHex, function(txid) { - self.log('BITCOND txid:', txid); //TODO + self.log('BITCOIND txid:', txid); //TODO if (txid) { self.txProposals.setSent(ntxid, txid); self.sendTxProposals(null, ntxid); @@ -545,8 +544,6 @@ Wallet.prototype.getUnspent = function(cb) { Wallet.prototype.createTx = function(toAddress, amountSatStr, opts, cb) { var self = this; - alert(amountSatStr); - alert(JSON.stringify(opts)); if (typeof opts === 'function') { cb = opts; opts = {}; @@ -565,7 +562,7 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, opts, cb) { self.store(); self.emit('txProposalsUpdated'); } - return cb(); + return cb(ntxid); }); }; diff --git a/package.json b/package.json index fdcbedbfb..b7f396c87 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "bitcore": "git://github.com/bitpay/bitcore.git", "chai": "~1.9.1", "sinon": "~1.9.1", - "node-cryptojs-aes": "=0.4.0" + "node-cryptojs-aes": "=0.4.0", + "async": "~0.9.0" } } diff --git a/test/find_m_n.js b/test/find_m_n.js index 678a3d5dd..bba548b46 100755 --- a/test/find_m_n.js +++ b/test/find_m_n.js @@ -2,6 +2,7 @@ 'use strict'; +var async = require('async'); var bitcore = require('bitcore'); var PublicKeyRing = require('../js/models/core/PublicKeyRing'); var PrivateKey = require('../js/models/core/PrivateKey'); @@ -24,7 +25,7 @@ var nn = 'livenet'; for (var n = 1; n < N_LIMIT; n++) { for (var m = 1; m <= n; m++) { // case m-of-n - console.log('case '+m+'-of-'+n); + console.log('case ' + m + '-of-' + n); // create full pkr var publicKeyRing = new PublicKeyRing({ networkName: nn, @@ -32,6 +33,7 @@ for (var n = 1; n < N_LIMIT; n++) { totalCopayers: n, }); var privateKey = null; + var pks = []; for (var i = 0; i < n; i++) { var pk = new PrivateKey({ networkName: nn @@ -41,6 +43,7 @@ for (var n = 1; n < N_LIMIT; n++) { } else { publicKeyRing.addCopayer(pk.getExtendedPublicKeyString(), 'dummy'); } + pks.push(pk); } var opts = {}; @@ -53,13 +56,36 @@ for (var n = 1; n < N_LIMIT; n++) { var w = new WalletFactory(opts).create(opts); var addr = w.generateAddress(); - console.log('\t receive addr='+addr); + console.log('\t receive addr=' + addr); var toAddress = 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'; var amount = '5000000'; - - - + // create fake utxo + var utxos = [{ + 'address': addr, + 'txid': '659e4e6d9c840e57aee6ebe35f2511cdeb848d786938f0b6b4f1b00de09b29da', + 'vout': 1, + 'ts': 1400682132, + 'scriptPubKey': 'a914e4a6744eeed5571cff9e427cbb5dd5e1a2d1b2fa87', + 'amount': 10.000, + 'confirmations': 100 + }]; + var ntxid = w.createTxSync(toAddress, amount, utxos); + console.log('\t ntxid =' + ntxid); + var sign = function(pk, cb) { + w.sign(ntxid, cb); + } + async.each(pks, sign, function(err) { + if (err) { + throw new Error(err); + } + }); + var txp = w.txProposals.txps[ntxid]; + var tx = txp.builder.build(); + console.log(tx.isComplete()); + var scriptSig = tx.ins[0].getScript(); + console.log(scriptSig.toHumanReadable()); + console.log(scriptSig.serialize().length); } } From 89cdfb3f7cfe8f628cacab36017cc63f664c9c9d Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 21 May 2014 16:10:39 -0300 Subject: [PATCH 3/4] finish m_n script --- js/controllers/send.js | 2 +- js/models/core/Wallet.js | 3 ++- test/find_m_n.js | 35 +++++++++++++++++------------------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index 5a78389cc..9c8850786 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -96,7 +96,7 @@ angular.module('copay.send').controller('SendController', //alert(JSON.stringify(qrcode.process(context))); qrcode.decode(); } catch (e) { - alert(e); + console.log('error decoding QR: '+e); } }, 1500); }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 442c44449..36e4baf0b 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -3,6 +3,7 @@ var imports = require('soop').imports(); var bitcore = require('bitcore'); +var bignum = bitcore.Bignum; var coinUtil = bitcore.util; var buffertools = bitcore.buffertools; var Builder = bitcore.TransactionBuilder; @@ -571,7 +572,7 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, utxos, opts) { var priv = this.privateKey; opts = opts || {}; - var amountSat = bitcore.bignum(amountSatStr); + var amountSat = bignum(amountSatStr); if (!pkr.isComplete()) { throw new Error('publicKeyRing is not complete'); diff --git a/test/find_m_n.js b/test/find_m_n.js index bba548b46..4ea1c7518 100755 --- a/test/find_m_n.js +++ b/test/find_m_n.js @@ -19,10 +19,11 @@ var WalletFactory = require('soop').load('../js/models/core/WalletFactory', { var Key = bitcore.Key; -var N_LIMIT = 16; +var N_LIMIT = 20; var nn = 'livenet'; -for (var n = 1; n < N_LIMIT; n++) { +for (var n = 1; n <= N_LIMIT; n++) { + var end = false; for (var m = 1; m <= n; m++) { // case m-of-n console.log('case ' + m + '-of-' + n); @@ -64,28 +65,26 @@ for (var n = 1; n < N_LIMIT; n++) { // create fake utxo var utxos = [{ 'address': addr, - 'txid': '659e4e6d9c840e57aee6ebe35f2511cdeb848d786938f0b6b4f1b00de09b29da', + 'txid': '82a974b72d3135152043989652e687e2966c651ba4822274926221017ea072d2', 'vout': 1, - 'ts': 1400682132, - 'scriptPubKey': 'a914e4a6744eeed5571cff9e427cbb5dd5e1a2d1b2fa87', - 'amount': 10.000, - 'confirmations': 100 + 'ts': 1400696213, + 'scriptPubKey': 'a914b2562c950498ff48ad3479ca1c2dfda2b0273e2287', + 'amount': 10.0, + 'confirmations': 2 }]; var ntxid = w.createTxSync(toAddress, amount, utxos); console.log('\t ntxid =' + ntxid); - var sign = function(pk, cb) { - w.sign(ntxid, cb); - } - async.each(pks, sign, function(err) { - if (err) { - throw new Error(err); - } - }); var txp = w.txProposals.txps[ntxid]; var tx = txp.builder.build(); - console.log(tx.isComplete()); var scriptSig = tx.ins[0].getScript(); - console.log(scriptSig.toHumanReadable()); - console.log(scriptSig.serialize().length); + var size = scriptSig.serialize().length; + console.log('\t scriptSig size: '+size); + if (size > 500) { + if (m === 1) { + end = true; + } + break; + } } + if (end) break; } From 88844f1ff4a02681634e3fe1e1b9a3080fb788bf Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 21 May 2014 16:15:38 -0300 Subject: [PATCH 4/4] update limit values based on scriptSig experiments --- config.template.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.template.js b/config.template.js index 888c72a60..ee4baf045 100644 --- a/config.template.js +++ b/config.template.js @@ -79,8 +79,8 @@ var defaultConfig = { } }, limits: { - totalCopayers: 10, - mPlusN: 15 + totalCopayers: 12, + mPlusN: 100 }, wallet: { requiredCopayers: 2,