def update_signatures(self, raw): """Add new signatures to a transaction""" d = deserialize(raw) for i, txin in enumerate(self.inputs()): sigs1 = txin.get('signatures') sigs2 = d['inputs'][i].get('signatures') for sig in sigs2: if sig in sigs1: continue for_sig = Hash(self.tx_for_sig(i).decode('hex')) # der to string order = ecdsa.ecdsa.generator_secp256k1.order() r, s = ecdsa.util.sigdecode_der(sig.decode('hex'), order) sig_string = ecdsa.util.sigencode_string(r, s, order) pubkeys = txin.get('pubkeys') compressed = True for recid in range(4): public_key = MyVerifyingKey.from_signature(sig_string, recid, for_sig, curve=SECP256k1) pubkey = point_to_ser(public_key.pubkey.point, compressed).encode('hex') if pubkey in pubkeys: public_key.verify_digest( sig_string, for_sig, sigdecode=ecdsa.util.sigdecode_string) j = pubkeys.index(pubkey) print_error("adding sig", i, j, pubkey, sig) self._inputs[i]['signatures'][j] = sig self._inputs[i]['x_pubkeys'][j] = pubkey break # redo raw self.raw = self.serialize()
def verify_message(address, signature, message): try: EC_KEY.verify_message(address, signature, message) return True except Exception as e: print_error("Verification error: {0}".format(e)) return False
def parse_proposals_subscription_result(results): """Parse the proposals subscription response.""" proposals = [] for k, result in results.items(): kwargs = { 'proposal_name': result['Name'], 'proposal_url': result['URL'], 'start_block': int(result['BlockStart']), 'end_block': int(result['BlockEnd']), 'payment_amount': result['MonthlyPayment'], 'address': result['PaymentAddress'] } fee_txid_key = 'FeeTXHash' if result.get('FeeTXHash') else 'FeeHash' kwargs['fee_txid'] = result[fee_txid_key] yes_count_key = 'YesCount' if result.get('YesCount') else 'Yeas' kwargs['yes_count'] = result[yes_count_key] no_count_key = 'NoCount' if result.get('NoCount') else 'Nays' kwargs['no_count'] = result[no_count_key] payment_amount = Decimal(str(kwargs['payment_amount'])) kwargs['payment_amount'] = pow(10, 8) * payment_amount proposals.append(BudgetProposal.from_dict(kwargs)) print_error('Received updated budget proposal information (%d proposals)' % len(proposals)) return proposals
def give_error(self, message, clear_client = False): print_error(message) if not self.signing: self.handler.show_error(message) else: self.signing = False if clear_client: self.plugin.client = None self.device_checked = False raise Exception(message)
def sign_message(self, message, compressed, address): signature = self.sign(Hash(msg_magic(message))) for i in range(4): sig = chr(27 + i + (4 if compressed else 0)) + signature try: self.verify_message(address, sig, message) return sig except Exception as e: print_error('Error for verifying with "%s": %s' % (chr(27 + i + (4 if compressed else 0)), str(e))) continue else: raise Exception("error: cannot sign message")
def submit_thread(): for i, (proposal_name, txid) in enumerate(self.unsubmitted_proposals): errmsg, success = self.parent.masternode_manager.submit_proposal( proposal_name, save=False) results[i] = (proposal_name, errmsg, success) if success: print_error('Sucessfully submitted proposal "%s"' % proposal_name) else: print_error('Failed to submit proposal "%s": %s' % (proposal_name, errmsg)) return results
def get_payment_request(url): u = urlparse.urlparse(url) if u.scheme in ['http', 'https']: response = requests.request('GET', url, headers=REQUEST_HEADERS) data = response.content print_error('fetched payment request', url, len(data)) elif u.scheme == 'file': with open(u.path, 'r') as f: data = f.read() else: raise BaseException("unknown scheme", url) pr = PaymentRequest(data) return pr
def query(url, rtype): # 8.8.8.8 is Google's public DNS server nameservers = ['8.8.8.8'] ns = nameservers[0] try: out = get_and_validate(ns, url, rtype) validated = True except BaseException as e: #traceback.print_exc(file=sys.stderr) print_error("DNSSEC error:", str(e)) resolver = dns.resolver.get_default_resolver() out = resolver.query(url, rtype) validated = False return out, validated
def create_proposal_tx(self, proposal_name, password, save=True): """Create a fee transaction for proposal_name.""" proposal = self.get_proposal(proposal_name) if proposal.fee_txid: print_error('Warning: Proposal "%s" already has a fee tx: %s' % (proposal_name, proposal.fee_txid)) if proposal.submitted: raise Exception('Proposal has already been submitted') h = bitcoin.hash_decode(proposal.get_hash()).encode('hex') script = '6a20' + h # OP_RETURN hash outputs = [(bitcoin.TYPE_SCRIPT, script.decode('hex'), BUDGET_FEE_TX)] tx = self.wallet.mktx(outputs, password, self.config) proposal.fee_txid = tx.hash() if save: self.save() return tx
def masternode_subscription_response(self, response): """Callback for when a masternode's status changes.""" collateral = response['params'][0] mn = None for masternode in self.masternodes: if masternode.get_collateral_str() == collateral: mn = masternode break if not mn: return status = response['result'] if status is None: status = False print_error('Received updated status for masternode %s: "%s"' % (mn.alias, status)) self.masternode_statuses[collateral] = status
def requires_fee(self, wallet): # see https://en.bitcoin.it/wiki/Transaction_fees # # size must be smaller than 1 kbyte for free tx size = len(self.serialize(-1)) / 2 if size >= 10000: return True # all outputs must be 0.01 BTC or larger for free tx for addr, value in self.get_outputs(): if value < 1000000: return True # priority must be large enough for free tx threshold = 57600000 weight = 0 for txin in self.inputs(): age = wallet.get_confirmations(txin["prevout_hash"])[0] weight += txin["value"] * age priority = weight / size print_error(priority, threshold) return priority < threshold
def __init__(self, lang=None): if lang in [None, '']: lang = i18n.language.info().get('language', 'en') print_error('language', lang) filename = filenames.get(lang[0:2], 'english.txt') if getattr(sys, 'frozen', None): path = os.path.join(sys._MEIPASS + "/lib/wordlist", filename) else: path = os.path.join(os.path.dirname(__file__), 'wordlist', filename) s = open(path, 'r').read().strip() s = unicodedata.normalize('NFKD', s.decode('utf8')) lines = s.split('\n') self.wordlist = [] for line in lines: line = line.split('#')[0] line = line.strip(' \r') assert ' ' not in line if line: self.wordlist.append(line) print_error("wordlist has %d words" % len(self.wordlist))
def import_masternode_conf_lines(self, conf_lines, password): """Import a list of MasternodeConfLine.""" def already_have(line): for masternode in self.masternodes: # Don't let aliases collide. if masternode.alias == line.alias: return True # Don't let outputs collide. if masternode.vin.get( 'prevout_hash') == line.txid and masternode.vin.get( 'prevout_n') == line.output_index: return True return False num_imported = 0 for conf_line in conf_lines: if already_have(conf_line): continue # Import delegate WIF key for signing last_ping. self.import_masternode_delegate(conf_line.wif) public_key = bitcoin.public_key_from_private_key(conf_line.wif) addr = conf_line.addr.split(':') addr = NetworkAddress(ip=addr[0], port=int(addr[1])) vin = { 'prevout_hash': conf_line.txid, 'prevout_n': conf_line.output_index } mn = MasternodeAnnounce(alias=conf_line.alias, vin=vin, delegate_key=public_key, addr=addr) self.add_masternode(mn) try: self.populate_masternode_output(mn.alias) except Exception as e: print_error(str(e)) num_imported += 1 return num_imported
def make_seed(self, num_bits=128, prefix=version.SEED_PREFIX, custom_entropy=1): n = int(math.ceil(math.log(custom_entropy, 2))) # bits of entropy used by the prefix k = len(prefix) * 4 # we add at least 16 bits n_added = max(16, k + num_bits - n) print_error("make_seed", prefix, "adding %d bits" % n_added) my_entropy = ecdsa.util.randrange(pow(2, n_added)) nonce = 0 while True: nonce += 1 i = custom_entropy * (my_entropy + nonce) seed = self.mnemonic_encode(i) assert i == self.mnemonic_decode(seed) if is_old_seed(seed): continue if is_new_seed(seed, prefix): break print_error('%d words' % len(seed.split())) return seed
def sign(self, keypairs): for i, txin in enumerate(self.inputs()): num = txin['num_sig'] for x_pubkey in txin['x_pubkeys']: signatures = filter(None, txin['signatures']) if len(signatures) == num: # txin is complete break if x_pubkey in keypairs.keys(): print_error("adding signature for", x_pubkey) # add pubkey to txin txin = self._inputs[i] x_pubkeys = txin['x_pubkeys'] ii = x_pubkeys.index(x_pubkey) sec = keypairs[x_pubkey] pubkey = public_key_from_private_key(sec) txin['x_pubkeys'][ii] = pubkey txin['pubkeys'][ii] = pubkey self._inputs[i] = txin # add signature for_sig = Hash(self.tx_for_sig(i).decode('hex')) pkey = regenerate_key(sec) secexp = pkey.secret private_key = bitcoin.MySigningKey.from_secret_exponent( secexp, curve=SECP256k1) public_key = private_key.get_verifying_key() sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_der_canonize) assert public_key.verify_digest( sig, for_sig, sigdecode=ecdsa.util.sigdecode_der) txin['signatures'][ii] = sig.encode('hex') self._inputs[i] = txin print_error("is_complete", self.is_complete()) self.raw = self.serialize()
import sys import platform from electrum_sib.plugins import BasePlugin, hook from electrum_sib_gui.qt.util import WaitingDialog, EnterButton, WindowModalDialog from electrum_sib.util import print_msg, print_error from electrum_sib.i18n import _ from PyQt4.QtGui import * from PyQt4.QtCore import * try: import amodem.audio import amodem.main import amodem.config print_error('Audio MODEM is available.') amodem.log.addHandler(amodem.logging.StreamHandler(sys.stderr)) amodem.log.setLevel(amodem.logging.INFO) except ImportError: amodem = None print_error('Audio MODEM is not found.') class Plugin(BasePlugin): def __init__(self, parent, config, name): BasePlugin.__init__(self, parent, config, name) if self.is_available(): self.modem_config = amodem.config.slowest() self.library_name = {'Linux': 'libportaudio.so'}[platform.system()] def is_available(self):
def parse_scriptSig(d, bytes): try: decoded = [x for x in script_GetOp(bytes)] except Exception: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return # payto_pubkey match = [opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') d['address'] = "(pubkey)" d['signatures'] = [sig] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') x_pubkey = decoded[1][1].encode('hex') try: signatures = parse_sig([sig]) pubkey, address = parse_xpub(x_pubkey) except: import traceback traceback.print_exc(file=sys.stdout) print_error("cannot find address in input script", bytes.encode('hex')) return d['signatures'] = signatures d['x_pubkeys'] = [x_pubkey] d['num_sig'] = 1 d['pubkeys'] = [pubkey] d['address'] = address return # p2sh transaction, m of n match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1) if not match_decoded(decoded, match): print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = [x[1].encode('hex') for x in decoded[1:-1]] dec2 = [x for x in script_GetOp(decoded[-1][1])] m = dec2[0][0] - opcodes.OP_1 + 1 n = dec2[-2][0] - opcodes.OP_1 + 1 op_m = opcodes.OP_1 + m - 1 op_n = opcodes.OP_1 + n - 1 match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not match_decoded(dec2, match_multisig): print_error("cannot find address in input script", bytes.encode('hex')) return x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2]) pubkeys = [parse_xpub(x)[0] for x in x_pubkeys] # xpub, addr = parse_xpub() redeemScript = Transaction.multisig_script(pubkeys, m) # write result in d d['num_sig'] = m d['signatures'] = parse_sig(x_sig) d['x_pubkeys'] = x_pubkeys d['pubkeys'] = pubkeys d['redeemScript'] = redeemScript d['address'] = hash_160_to_bc_address(hash_160(redeemScript.decode('hex')), bitcoin.SCRIPT_ADDR)
def sign_done(proposal, tx): print_error('proposal tx sign done: %s' % proposal.proposal_name) if tx: label = _('Budget Proposal Tx: ') + proposal.proposal_name self.parent.broadcast_transaction(tx, label) self.parent.masternode_manager.save()