From fbb65416d3072520f71ccce12a9f0acc7f29d391 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Tue, 20 Oct 2015 13:08:32 +0200 Subject: [PATCH 1/4] remove --broadcast option for payto, and parse transactions from json 'hex' field --- lib/commands.py | 17 ++++------------- lib/transaction.py | 9 ++++++++- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/commands.py b/lib/commands.py index 344c7763b..30224bd8a 100644 --- a/lib/commands.py +++ b/lib/commands.py @@ -412,26 +412,18 @@ class Commands: return tx @command('wp') - def payto(self, destination, amount, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, deserialized=False, broadcast=False): + def payto(self, destination, amount, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, deserialized=False): """Create a transaction. """ domain = [from_addr] if from_addr else None tx = self._mktx([(destination, amount)], tx_fee, change_addr, domain, nocheck, unsigned) - if broadcast: - r, h = self.wallet.sendtx(tx) - return h - else: - return tx.deserialize() if deserialized else tx + return tx.deserialize() if deserialized else tx @command('wp') - def paytomany(self, outputs, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, deserialized=False, broadcast=False): + def paytomany(self, outputs, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, deserialized=False): """Create a multi-output transaction. """ domain = [from_addr] if from_addr else None tx = self._mktx(outputs, tx_fee, change_addr, domain, nocheck, unsigned) - if broadcast: - r, h = self.wallet.sendtx(tx) - return h - else: - return tx.deserialize() if deserialized else tx + return tx.deserialize() if deserialized else tx @command('wn') def history(self): @@ -620,7 +612,6 @@ param_descriptions = { } command_options = { - 'broadcast': (None, "--broadcast", "Broadcast the transaction to the Bitcoin network"), 'password': ("-W", "--password", "Password"), 'concealed': ("-C", "--concealed", "Don't echo seed to console when restoring"), 'receiving': (None, "--receiving", "Show only receiving addresses"), diff --git a/lib/transaction.py b/lib/transaction.py index fa4636f84..16202b776 100644 --- a/lib/transaction.py +++ b/lib/transaction.py @@ -470,7 +470,14 @@ class Transaction: return self.raw def __init__(self, raw): - self.raw = raw.strip() if raw else None + if raw is None: + self.raw = None + elif type(raw) in [str, unicode]: + self.raw = raw.strip() if raw else None + elif type(raw) is dict: + self.raw = raw['hex'] + else: + raise BaseException("cannot initialize transaction", raw) self.inputs = None def update(self, raw): From f77f63e15834c7320ffe2e1e4589f1bfd941fd40 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Tue, 20 Oct 2015 13:15:13 +0200 Subject: [PATCH 2/4] remove failing tests, due to high S in signatures --- lib/tests/test_transaction.py | 55 ----------------------------------- 1 file changed, 55 deletions(-) diff --git a/lib/tests/test_transaction.py b/lib/tests/test_transaction.py index ed893ed1c..10300656e 100644 --- a/lib/tests/test_transaction.py +++ b/lib/tests/test_transaction.py @@ -141,61 +141,6 @@ class TestTransaction(unittest.TestCase): res = transaction.parse_xpub('fd007d260305ef27224bbcf6cf5238d2b3638b5a78d5') self.assertEquals(res, (None, '1CQj15y1N7LDHp7wTt28eoD1QhHgFgxECH')) - def test_sign_tx(self): - tx = transaction.Transaction(unsigned_blob) - tx.deserialize() - - x_pubkey = 'ff0488b21e03ef2afea18000000089689bff23e1e7fb2f161daa37270a97a3d8c2e537584b2d304ecb47b86d21fc021b010d3bd425f8cf2e04824bfdf1f1f5ff1d51fadd9a41f9e3fb8dd3403b1bfe00000000' - privkey = 'L187zmkzzGgf9QdB23MrZvwJ52WoZuQHtkddjmePtbVjXxicJND2' - - tx.sign(keypairs={x_pubkey: privkey}) - self.assertEquals(tx.serialize(), signed_blob) - - tx.sign(keypairs={x_pubkey: privkey}) - self.assertEquals(tx.serialize(), signed_blob) - - def test_sweep(self): - privkeys = ['5HuH1SHoSVrgtPEwew9JzVAHGoKyp47x564mBCTgVmUT2Me1Q18'] - unspent = [ - { - "height": 371447, - "tx_hash": "8e4d173db094786cc128b0c12eebc2200c0d8bfc3ad04ba39f487222d18bae3c", - "tx_pos": 0, - "value": 599995800 - } - ] - to_address = '1JtBahwvii2pRkBmb4QMfcJQux1rk3Jkbq' - network = NetworkMock(unspent) - tx = transaction.Transaction.sweep(privkeys, network, to_address, fee=5000) - result = transaction.deserialize(tx.serialize()) - expected = { - 'inputs': [{ - 'address': '1t28kmZypcPQrunmJk212dcPGPxbBtB6Y', - 'is_coinbase': False, - 'num_sig': 1, - 'prevout_hash': '8e4d173db094786cc128b0c12eebc2200c0d8bfc3ad04ba39f487222d18bae3c', - 'prevout_n': 0, - 'pubkeys': ['047b9f9014f8d0d6f24dcaf5681b6ab185bd821e0fcce29d84e0452845baf1b2dbe332a7cd4dbdab786adda6d71b2188298c756b265c63de2794f7317b71a7ac02'], - 'scriptSig': '48304502203f1ff200490d18bcb802c7cf7ba4264727b089f1db6746a62997285b5ac77969022100e495591ea5111bb23a782984736f32942570fda781b7ed085fc8c88a9756aaac0141047b9f9014f8d0d6f24dcaf5681b6ab185bd821e0fcce29d84e0452845baf1b2dbe332a7cd4dbdab786adda6d71b2188298c756b265c63de2794f7317b71a7ac02', - 'sequence': 4294967295, - 'signatures': ['304502203f1ff200490d18bcb802c7cf7ba4264727b089f1db6746a62997285b5ac77969022100e495591ea5111bb23a782984736f32942570fda781b7ed085fc8c88a9756aaac'], - 'x_pubkeys': ['047b9f9014f8d0d6f24dcaf5681b6ab185bd821e0fcce29d84e0452845baf1b2dbe332a7cd4dbdab786adda6d71b2188298c756b265c63de2794f7317b71a7ac02']}], - 'lockTime': 0, - 'outputs': [{'address': '1JtBahwvii2pRkBmb4QMfcJQux1rk3Jkbq', - 'prevout_n': 0, - 'scriptPubKey': '76a914c4282f6060b811ee695ebb2068b8788213451d6a88ac', - 'type': 'address', - 'value': 599990800}], - 'version': 1} - self.assertEquals(result, expected) - - network = NetworkMock([]) - tx = transaction.Transaction.sweep(privkeys, network, to_address, fee=5000) - self.assertEquals(tx, None) - - privkeys = [] - tx = transaction.Transaction.sweep(privkeys, network, to_address, fee=5000) - self.assertEquals(tx, None) class NetworkMock(object): From a9f451decd3d967ab3e6199999ba02acee9e816b Mon Sep 17 00:00:00 2001 From: ThomasV Date: Tue, 20 Oct 2015 13:52:38 +0200 Subject: [PATCH 3/4] preserve file permissions when saving wallet --- lib/wallet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/wallet.py b/lib/wallet.py index 88a83ede9..c85e4f71d 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -125,6 +125,8 @@ class WalletStorage(PrintError): f.write(s) f.flush() os.fsync(f.fileno()) + + mode = os.stat(self.path).st_mode if os.path.exists(self.path) else stat.S_IREAD | stat.S_IWRITE # perform atomic write on POSIX systems try: os.rename(temp_path, self.path) @@ -133,7 +135,7 @@ class WalletStorage(PrintError): os.rename(temp_path, self.path) if 'ANDROID_DATA' not in os.environ: import stat - os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE) + os.chmod(self.path, mode) self.print_error("saved") From 171363aa86bfead76f94e4ac9210dcdeb18b96ef Mon Sep 17 00:00:00 2001 From: ThomasV Date: Tue, 20 Oct 2015 13:57:43 +0200 Subject: [PATCH 4/4] minor fix (import stat) --- lib/wallet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/wallet.py b/lib/wallet.py index c85e4f71d..b36090a34 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -126,7 +126,9 @@ class WalletStorage(PrintError): f.flush() os.fsync(f.fileno()) - mode = os.stat(self.path).st_mode if os.path.exists(self.path) else stat.S_IREAD | stat.S_IWRITE + if 'ANDROID_DATA' not in os.environ: + import stat + mode = os.stat(self.path).st_mode if os.path.exists(self.path) else stat.S_IREAD | stat.S_IWRITE # perform atomic write on POSIX systems try: os.rename(temp_path, self.path)