electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 0d529115612434b29b30e5d11714fc7625fe4d6c
parent d57af0db33b57d7ad0bc938810d42d25accc405c
Author: ThomasV <thomasv@electrum.org>
Date:   Thu, 14 Jan 2016 17:15:50 +0100

define constants for tx output types

Diffstat:
Mgui/android.py | 9++++-----
Mgui/kivy/uix/screens.py | 3+--
Mgui/qt/main_window.py | 6+++---
Mgui/qt/paytoedit.py | 6+++---
Mgui/stdio.py | 4++--
Mgui/text.py | 12++++++------
Mlib/bitcoin.py | 6++++++
Mlib/coinchooser.py | 4++--
Mlib/commands.py | 8++++----
Mlib/transaction.py | 23++++++++++++-----------
Mlib/wallet.py | 8++++----
Mplugins/ledger/ledger.py | 4++--
Mplugins/trezor/plugin.py | 5+++--
Mplugins/trustedcoin/trustedcoin.py | 2+-
14 files changed, 53 insertions(+), 47 deletions(-)

diff --git a/gui/android.py b/gui/android.py @@ -21,12 +21,12 @@ from __future__ import absolute_import import android +from decimal import Decimal +import datetime, re from electrum import SimpleConfig, Wallet, WalletStorage, format_satoshis -from electrum.bitcoin import is_address, COIN +from electrum.bitcoin import is_address, COIN, TYPE_ADDRESS from electrum import util -from decimal import Decimal -import datetime, re def modal_dialog(title, msg = None): @@ -442,9 +442,8 @@ def pay_to(recipient, amount, label): droid.dialogCreateSpinnerProgress("Electrum", "signing transaction...") droid.dialogShow() - try: - tx = wallet.mktx([('address', recipient, amount)], password, config) + tx = wallet.mktx([(TYPE_ADDRESS, recipient, amount)], password, config) except Exception as e: modal_dialog('error', e.message) droid.dialogDismiss() diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py @@ -26,7 +26,6 @@ from context_menu import ContextMenu from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED - class CScreen(Factory.Screen): __events__ = ('on_activate', 'on_deactivate', 'on_enter', 'on_leave') @@ -254,7 +253,7 @@ class SendScreen(CScreen): except: self.app.show_error(_('Invalid amount') + ':\n' + self.screen.amount) return - outputs = [('address', address, amount)] + outputs = [(bitcoin.TYPE_ADDRESS, address, amount)] message = unicode(self.screen.message) fee = None self.app.protected(self.send_tx, (outputs, fee, message)) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -34,7 +34,7 @@ import PyQt4.QtCore as QtCore import icons_rc -from electrum.bitcoin import COIN, is_valid +from electrum.bitcoin import COIN, is_valid, TYPE_ADDRESS from electrum.plugins import run_hook from electrum.i18n import _ from electrum.util import block_explorer, block_explorer_info, block_explorer_URL @@ -1076,7 +1076,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): fee = self.fee_e.get_amount() if freeze_fee else None if not outputs: addr = self.payto_e.payto_address if self.payto_e.payto_address else self.dummy_address - outputs = [('address', addr, amount)] + outputs = [(TYPE_ADDRESS, addr, amount)] try: tx = self.wallet.make_unsigned_transaction(self.get_coins(), outputs, self.config, fee) self.not_enough_funds = False @@ -1180,7 +1180,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): if addr is None: self.show_error(_('Bitcoin Address is None')) return - if _type == 'address' and not bitcoin.is_address(addr): + if _type == TYPE_ADDRESS and not bitcoin.is_address(addr): self.show_error(_('Invalid Bitcoin Address')) return if amount is None: diff --git a/gui/qt/paytoedit.py b/gui/qt/paytoedit.py @@ -77,11 +77,11 @@ class PayToEdit(ScanQRTextEdit): if n: script = str(n.group(1)).decode('hex') amount = self.parse_amount(y) - return 'script', script, amount + return bitcoin.TYPE_SCRIPT, script, amount else: address = self.parse_address(x) amount = self.parse_amount(y) - return 'address', address, amount + return bitcoin.TYPE_ADDRESS, address, amount def parse_amount(self, x): p = pow(10, self.amount_edit.decimal_point()) @@ -149,7 +149,7 @@ class PayToEdit(ScanQRTextEdit): amount = self.amount_edit.get_amount() except: amount = None - self.outputs = [('address', self.payto_address, amount)] + self.outputs = [(bitcoin.TYPE_ADDRESS, self.payto_address, amount)] return self.outputs[:] diff --git a/gui/stdio.py b/gui/stdio.py @@ -3,7 +3,7 @@ _ = lambda x:x #from i18n import _ from electrum.wallet import WalletStorage, Wallet from electrum.util import format_satoshis, set_verbosity, StoreDict -from electrum.bitcoin import is_valid, COIN +from electrum.bitcoin import is_valid, COIN, TYPE_ADDRESS from electrum.network import filter_protocol import sys, getpass, datetime @@ -187,7 +187,7 @@ class ElectrumGui: if c == "n": return try: - tx = self.wallet.mktx( [(self.str_recipient, amount)], password, self.config, fee) + tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)], password, self.config, fee) except Exception as e: print(str(e)) return diff --git a/gui/text.py b/gui/text.py @@ -1,13 +1,14 @@ +import tty, sys import curses, datetime, locale from decimal import Decimal -_ = lambda x:x + from electrum.util import format_satoshis, set_verbosity from electrum.util import StoreDict -from electrum.bitcoin import is_valid, COIN - +from electrum.bitcoin import is_valid, COIN, TYPE_ADDRESS from electrum import Wallet, WalletStorage -import tty, sys +_ = lambda x:x + class ElectrumGui: @@ -327,9 +328,8 @@ class ElectrumGui: return else: password = None - try: - tx = self.wallet.mktx( [(self.str_recipient, amount)], password, self.config, fee) + tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)], password, self.config, fee) except Exception as e: self.show_message(str(e)) return diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -34,6 +34,12 @@ RECOMMENDED_FEE = 50000 COINBASE_MATURITY = 100 COIN = 100000000 +# supported types of transction outputs +TYPE_ADDRESS = 0 +TYPE_PUBKEY = 1 +TYPE_SCRIPT = 2 + + # AES encryption EncodeAES = lambda secret, s: base64.b64encode(aes.encryptData(secret,s)) DecodeAES = lambda secret, e: aes.decryptData(secret, base64.b64decode(e)) diff --git a/lib/coinchooser.py b/lib/coinchooser.py @@ -20,7 +20,7 @@ from collections import defaultdict, namedtuple from random import choice, randint, shuffle from math import floor, log10 -from bitcoin import COIN +from bitcoin import COIN, TYPE_ADDRESS from transaction import Transaction from util import NotEnoughFunds, PrintError, profiler @@ -72,7 +72,7 @@ class CoinChooserBase(PrintError): # size of the change output, add it to the transaction. dust = sum(amount for amount in amounts if amount < dust_threshold) amounts = [amount for amount in amounts if amount >= dust_threshold] - change = [('address', addr, amount) + change = [(TYPE_ADDRESS, addr, amount) for addr, amount in zip(change_addrs, amounts)] self.print_error('change:', change) if dust: diff --git a/lib/commands.py b/lib/commands.py @@ -31,7 +31,7 @@ from decimal import Decimal import util from util import print_msg, format_satoshis, print_stderr import bitcoin -from bitcoin import is_address, hash_160_to_bc_address, hash_160, COIN +from bitcoin import is_address, hash_160_to_bc_address, hash_160, COIN, TYPE_ADDRESS from transaction import Transaction import paymentrequest from paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED @@ -200,7 +200,7 @@ class Commands: break else: raise BaseException('Transaction output not in wallet', prevout_hash+":%d"%prevout_n) - outputs = map(lambda x: ('address', x[0], int(COIN*x[1])), outputs.items()) + outputs = map(lambda x: (TYPE_ADDRESS, x[0], int(COIN*x[1])), outputs.items()) tx = Transaction.from_io(tx_inputs, outputs) if not unsigned: self.wallet.sign_transaction(tx, self._password) @@ -404,14 +404,14 @@ class Commands: if fee is None: for i in inputs: self.wallet.add_input_info(i) - output = ('address', address, amount) + output = (TYPE_ADDRESS, address, amount) dummy_tx = Transaction.from_io(inputs, [output]) fee_per_kb = self.wallet.fee_per_kb(self.config) fee = dummy_tx.estimated_fee(fee_per_kb) amount -= fee else: amount = int(COIN*Decimal(amount)) - final_outputs.append(('address', address, amount)) + final_outputs.append((TYPE_ADDRESS, address, amount)) coins = self.wallet.get_spendable_coins(domain) tx = self.wallet.make_unsigned_transaction(coins, final_outputs, self.config, fee, change_addr) diff --git a/lib/transaction.py b/lib/transaction.py @@ -36,6 +36,7 @@ import random NO_SIGNATURE = 'ff' + class SerializationError(Exception): """ Thrown when there's a problem deserializing or serializing """ @@ -393,20 +394,20 @@ def get_address_from_output_script(bytes): # 65 BYTES:... CHECKSIG match = [ opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG ] if match_decoded(decoded, match): - return 'pubkey', decoded[0][1].encode('hex') + return TYPE_PUBKEY, decoded[0][1].encode('hex') # Pay-by-Bitcoin-address TxOuts look like: # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG match = [ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ] if match_decoded(decoded, match): - return 'address', hash_160_to_bc_address(decoded[2][1]) + return TYPE_ADDRESS, hash_160_to_bc_address(decoded[2][1]) # p2sh match = [ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ] if match_decoded(decoded, match): - return 'address', hash_160_to_bc_address(decoded[1][1],5) + return TYPE_ADDRESS, hash_160_to_bc_address(decoded[1][1],5) - return 'script', bytes + return TYPE_SCRIPT, bytes @@ -542,7 +543,7 @@ class Transaction: pubkey = public_key_from_private_key(privkey) address = address_from_private_key(privkey) u = network.synchronous_get(('blockchain.address.listunspent',[address])) - pay_script = klass.pay_script('address', address) + pay_script = klass.pay_script(TYPE_ADDRESS, address) for item in u: item['scriptPubKey'] = pay_script item['redeemPubkey'] = pubkey @@ -560,7 +561,7 @@ class Transaction: return total = sum(i.get('value') for i in inputs) - fee - outputs = [('address', to_address, total)] + outputs = [(TYPE_ADDRESS, to_address, total)] self = klass.from_io(inputs, outputs) self.sign(keypairs) return self @@ -577,9 +578,9 @@ class Transaction: @classmethod def pay_script(self, output_type, addr): - if output_type == 'script': + if output_type == TYPE_SCRIPT: return addr.encode('hex') - elif output_type == 'address': + elif output_type == TYPE_ADDRESS: addrtype, hash_160 = bc_address_to_hash_160(addr) if addrtype == 0: script = '76a9' # op_dup, op_hash_160 @@ -636,7 +637,7 @@ class Transaction: script += push_script(redeem_script) elif for_sig==i: - script = txin['redeemScript'] if p2sh else self.pay_script('address', address) + script = txin['redeemScript'] if p2sh else self.pay_script(TYPE_ADDRESS, address) else: script = '' @@ -797,9 +798,9 @@ class Transaction: """convert pubkeys to addresses""" o = [] for type, x, v in self.outputs: - if type == 'address': + if type == TYPE_ADDRESS: addr = x - elif type == 'pubkey': + elif type == TYPE_PUBKEY: addr = public_key_to_bc_address(x.decode('hex')) else: addr = 'SCRIPT ' + x.encode('hex') diff --git a/lib/wallet.py b/lib/wallet.py @@ -658,7 +658,7 @@ class Abstract_Wallet(PrintError): for i in inputs: self.add_input_info(i) addr = self.addresses(False)[0] - output = ('address', addr, sendable) + output = (TYPE_ADDRESS, addr, sendable) dummy_tx = Transaction.from_io(inputs, [output]) if fee is None: fee_per_kb = self.fee_per_kb(config) @@ -750,9 +750,9 @@ class Abstract_Wallet(PrintError): for n, txo in enumerate(tx.outputs): ser = tx_hash + ':%d'%n _type, x, v = txo - if _type == 'address': + if _type == TYPE_ADDRESS: addr = x - elif _type == 'pubkey': + elif _type == TYPE_PUBKEY: addr = public_key_to_bc_address(x.decode('hex')) else: addr = None @@ -924,7 +924,7 @@ class Abstract_Wallet(PrintError): def make_unsigned_transaction(self, coins, outputs, config, fixed_fee=None, change_addr=None): # check outputs for type, data, value in outputs: - if type == 'address': + if type == TYPE_ADDRESS: assert is_address(data), "Address " + data + " is invalid!" # Avoid index-out-of-range with coins[0] below diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py @@ -5,7 +5,7 @@ from sys import stderr from time import sleep import electrum -from electrum.bitcoin import EncodeBase58Check, DecodeBase58Check, public_key_to_bc_address, bc_address_to_hash_160 +from electrum.bitcoin import EncodeBase58Check, DecodeBase58Check, public_key_to_bc_address, bc_address_to_hash_160, TYPE_ADDRESS from electrum.i18n import _ from electrum.plugins import BasePlugin, hook from electrum.transaction import deserialize @@ -203,7 +203,7 @@ class BTChipWallet(BIP44_Wallet): if len(tx.outputs) > 2: # should never happen self.give_error("Transaction with more than 2 outputs not supported") for type, address, amount in tx.outputs: - assert type == 'address' + assert type == TYPE_ADDRESS if self.is_change(address): changePath = self.address_id(address) changeAmount = amount diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py @@ -7,7 +7,8 @@ from struct import pack from electrum.account import BIP32_Account from electrum.bitcoin import (bc_address_to_hash_160, xpub_from_pubkey, - public_key_to_bc_address, EncodeBase58Check) + public_key_to_bc_address, EncodeBase58Check, + TYPE_ADDRESS) from electrum.i18n import _ from electrum.plugins import BasePlugin, hook from electrum.transaction import (deserialize, is_extended_pubkey, @@ -427,7 +428,7 @@ class TrezorCompatiblePlugin(BasePlugin, ThreadJob): outputs = [] for type, address, amount in tx.outputs: - assert type == 'address' + assert type == TYPE_ADDRESS txoutputtype = self.types.TxOutputType() if wallet.is_change(address): address_path = wallet.address_id(address) diff --git a/plugins/trustedcoin/trustedcoin.py b/plugins/trustedcoin/trustedcoin.py @@ -234,7 +234,7 @@ class Wallet_2fa(Multisig_Wallet): fee = self.extra_fee() if fee: address = self.billing_info['billing_address'] - outputs = outputs + [('address', address, fee)] + outputs = outputs + [(TYPE_ADDRESS, address, fee)] try: return BIP32_Wallet.make_unsigned_transaction( self, coins, outputs, config, fixed_fee, change_addr)