Browse Source

Merge branch 'master' of https://github.com/spesmilo/electrum into uncopyable-seed

283
Fredrick Brennan 9 years ago
parent
commit
68af712c8b
  1. 17
      lib/commands.py
  2. 55
      lib/tests/test_transaction.py
  3. 9
      lib/transaction.py
  4. 6
      lib/wallet.py

17
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"),

55
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):

9
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):

6
lib/wallet.py

@ -125,6 +125,10 @@ class WalletStorage(PrintError):
f.write(s)
f.flush()
os.fsync(f.fileno())
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)
@ -133,7 +137,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")

Loading…
Cancel
Save