def recv_txio(self, nick, utxo_list, cj_pub, change_addr): if nick not in self.nonrespondants: debug('nick(' + nick + ') not in nonrespondants ' + str(self.nonrespondants)) return self.utxos[nick] = utxo_list order = self.db.execute('SELECT ordertype, txfee, cjfee FROM ' 'orderbook WHERE oid=? AND counterparty=?', (self.active_orders[nick], nick)).fetchone() utxo_data = common.bc_interface.query_utxo_set(self.utxos[nick]) if None in utxo_data: common.debug('ERROR outputs unconfirmed or already spent. utxo_data=' + pprint.pformat(utxo_data)) raise RuntimeError('killing taker, TODO handle this error') total_input = sum([d['value'] for d in utxo_data]) real_cjfee = calc_cj_fee(order['ordertype'], order['cjfee'], self.cj_amount) self.outputs.append({'address': change_addr, 'value': total_input - self.cj_amount - order['txfee'] + real_cjfee}) print 'fee breakdown for %s totalin=%d cjamount=%d txfee=%d realcjfee=%d' % (nick, total_input, self.cj_amount, order['txfee'], real_cjfee) cj_addr = btc.pubtoaddr(cj_pub, get_addr_vbyte()) self.outputs.append({'address': cj_addr, 'value': self.cj_amount}) self.cjfee_total += real_cjfee self.nonrespondants.remove(nick) if len(self.nonrespondants) > 0: debug('nonrespondants = ' + str(self.nonrespondants)) return debug('got all parts, enough to build a tx cjfeetotal=' + str(self.cjfee_total)) my_total_in = 0 for u, va in self.input_utxos.iteritems(): my_total_in += va['value'] #my_total_in = sum([va['value'] for u, va in self.input_utxos.iteritems()]) my_change_value = my_total_in - self.cj_amount - self.cjfee_total - self.my_txfee print 'fee breakdown for me totalin=%d txfee=%d cjfee_total=%d => changevalue=%d' % (my_total_in, self.my_txfee, self.cjfee_total, my_change_value) if self.my_change_addr == None: if my_change_value != 0 and abs(my_change_value) != 1: #seems you wont always get exactly zero because of integer rounding # so 1 satoshi extra or fewer being spent as miner fees is acceptable print 'WARNING CHANGE NOT BEING USED\nCHANGEVALUE = ' + str(my_change_value) else: self.outputs.append({'address': self.my_change_addr, 'value': my_change_value}) utxo_tx = [dict([('output', u)]) for u in sum(self.utxos.values(), [])] random.shuffle(utxo_tx) random.shuffle(self.outputs) tx = btc.mktx(utxo_tx, self.outputs) debug('obtained tx\n' + pprint.pformat(btc.deserialize(tx))) self.msgchan.send_tx(self.active_orders.keys(), tx) #now sign it ourselves here for index, ins in enumerate(btc.deserialize(tx)['ins']): utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index']) if utxo not in self.input_utxos.keys(): continue addr = self.input_utxos[utxo]['address'] tx = btc.sign(tx, index, self.wallet.get_key_from_addr(addr)) self.latest_tx = btc.deserialize(tx)
def showDetails(mnemonic, passphrase="", i=1): myMnemonic = mnemonic passphrase = passphrase mnemo = Mnemonic('english') seed = hexlify(mnemo.to_seed(myMnemonic, passphrase=passphrase)) print 'Seed:\t\t\t\t', seed priv = bitcoin.bip32_master_key(unhexlify(seed)) print 'Xpriv:\t\t\t\t', priv key = bitcoin.encode_privkey(bitcoin.bip32_extract_key(priv), 'wif_compressed') print 'Key:\t\t\t\t', key pub = bitcoin.bip32_privtopub(priv) print 'Derived public key:\t', pub pubHex = bitcoin.bip32_extract_key(pub) print 'public key (hex):\t', pubHex print 'Master Key address:\t', bitcoin.pubtoaddr(pubHex) print "" print "TREZOR Keys:" account = 0 derivedPrivateKey = bitcoin.bip32_ckd( bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44 + HARDENED), HARDENED), HARDENED + account) print 'Derived private key:', derivedPrivateKey privateKey = bitcoin.encode_privkey( bitcoin.bip32_extract_key(derivedPrivateKey), 'wif_compressed') print 'private key (wif):\t', privateKey derivedPublicKey = bitcoin.bip32_privtopub(derivedPrivateKey) print 'Derived public key:', derivedPublicKey publicKeyHex = bitcoin.privtopub(privateKey) print 'public key (hex):\t', publicKeyHex address = bitcoin.pubtoaddr(publicKeyHex) print 'address:\t\t\t', address print "" print "Account public keys (XPUB)" xpubs = [] for i in range(0, i): derivedPrivateKey = bitcoin.bip32_ckd( bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44 + HARDENED), HARDENED), HARDENED + i) xpub = bitcoin.bip32_privtopub(derivedPrivateKey) print 'Account', i, 'xpub:', xpub xpubs.append(xpub) return xpubs
def showDetails(mnemonic, passphrase="", i=1): myMnemonic = mnemonic passphrase = passphrase mnemo = Mnemonic('english') seed = hexlify(mnemo.to_seed(myMnemonic, passphrase=passphrase)) print 'Seed:\t\t\t\t', seed priv = bitcoin.bip32_master_key(unhexlify(seed)) print 'Xpriv:\t\t\t\t', priv key = bitcoin.encode_privkey(bitcoin.bip32_extract_key(priv), 'wif_compressed') print 'Key:\t\t\t\t', key pub = bitcoin.bip32_privtopub(priv) print 'Derived public key:\t', pub pubHex = bitcoin.bip32_extract_key(pub) print 'public key (hex):\t', pubHex print 'Master Key address:\t', bitcoin.pubtoaddr(pubHex) print "" print "TREZOR Keys:" account = 0 derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+account) print 'Derived private key:', derivedPrivateKey privateKey = bitcoin.encode_privkey(bitcoin.bip32_extract_key(derivedPrivateKey), 'wif_compressed') print 'private key (wif):\t', privateKey derivedPublicKey = bitcoin.bip32_privtopub(derivedPrivateKey) print 'Derived public key:', derivedPublicKey publicKeyHex = bitcoin.privtopub(privateKey) print 'public key (hex):\t', publicKeyHex address = bitcoin.pubtoaddr(publicKeyHex) print 'address:\t\t\t', address print "" print "Account public keys (XPUB)" xpubs = [] for i in range(0, i): derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+i) xpub = bitcoin.bip32_privtopub(derivedPrivateKey) print 'Account', i, 'xpub:', xpub xpubs.append(xpub) return xpubs
def becies_encode(ephemeral_pubkey, ciphertext, tag, pubkeys=[], num_to_activate=None, offsets=None): bout = BECIES_MAGIC_BYTES #0xc66b20 3-byte prefix? (encodes to xmsg in base64) isaddresses = bool(pubkeys) isgroup = bool(offsets) #a vli indicating the header contents flags. #offsets,and addresses are first two bits, rest are unused bout += _to_vli( int(isgroup) * BECIES_GROUP_FLAG + int(isaddresses) * BECIES_ADDRESSES_FLAG) if (isaddresses): bout += _to_vli(len(pubkeys)) bout += ''.join( [bitcoin.b58check_to_bin(bitcoin.pubtoaddr(p)) for p in pubkeys]) if (isgroup): bout += _to_vli( num_to_activate) #todo, num_to_activate must be strictly positive bout += _to_vli(len(offsets)) bout += ''.join([bitcoin.encode_privkey(priv) for priv in offsets]) bout += bitcoin.encode_pubkey(ephemeral_pubkey, 'bin_compressed') bout += _to_vli(len(ciphertext)) bout += ciphertext bout += tag #this has to come last for streaming mode too return bout
def generate_keypair(crypto, seed, password=None): """ Generate a private key and publickey for any currency, given a seed. That seed can be random, or a brainwallet phrase. """ pub_byte, priv_byte = get_magic_bytes(crypto) priv = sha256(seed) pub = privtopub(priv) if priv_byte >= 128: priv_byte -= 128 #pybitcointools bug priv_wif = encode_privkey(priv, 'wif_compressed', vbyte=priv_byte) if password: priv_wif = bip38_encrypt(priv_wif, password) compressed_pub = encode_pubkey(pub, 'hex_compressed') ret = { 'public': { 'hex_uncompressed': pub, 'hex': compressed_pub, 'address': pubtoaddr(compressed_pub, pub_byte) }, 'private': { 'wif': priv_wif } } if not password: # only these are valid when no bip38 password is supplied ret['private']['hex'] = encode_privkey(priv, 'hex_compressed', vbyte=priv_byte) ret['private']['hex_uncompressed'] = encode_privkey(priv, 'hex', vbyte=priv_byte) ret['private']['wif_uncompressed'] = encode_privkey(priv, 'wif', vbyte=priv_byte) return ret
def _derive_and_print(master_key: str, *path: int, derive_pub_key: bool = True, magicbyte: int = 0): master_pub_key = bitcoin.bip32_privtopub(master_key) derived_key = _derived_key(master_key, *path) if derive_pub_key: derived_bip32_pub_key = _derived_key(master_pub_key, *path) derived_pub_key = bitcoin.bip32_extract_key(derived_bip32_pub_key) else: derived_bip32_pub_key = derived_pub_key = 'N.A.' derived_pub_key_from_key = bitcoin.bip32_privtopub(derived_key) print(''' Derivation path: ({}), Derived BIP32 key: {}, Derived BIP32 public key: {}, BIP32 public key from derived BIP32 private: {}, Derived key: {}, Derived public key: {}, Public key from derived key: {}, BTC address: {} '''.format( ', '.join( str(x) if x <= 2**31 else str(x - 2**31) + '\'' for x in path), derived_key, derived_bip32_pub_key, derived_pub_key_from_key, bitcoin.bip32_extract_key(derived_key), derived_pub_key, bitcoin.privtopub(bitcoin.bip32_extract_key(derived_key)), bitcoin.pubtoaddr(bitcoin.privtopub( bitcoin.bip32_extract_key(derived_key)), magicbyte=magicbyte)))
def warp(passphrase, salt=""): s1 = scrypt.hash(passphrase + "\x01", salt+"\x01", N=2**18, r=8, p=1, buflen=32) s2 = pbkdf2(passphrase + "\x02", salt=salt+"\x02", keylen=32, rounds=2**16, prf="hmac-sha256") key = binascii.hexlify(xor(s1, s2)) return key, bitcoin.pubtoaddr(bitcoin.privtopub(key))
def generate_keypair(crypto, seed, password=None): """ Generate a private key and publickey for any currency, given a seed. That seed can be random, or a brainwallet phrase. """ pub_byte, priv_byte = get_magic_bytes(crypto) priv = sha256(seed) pub = privtopub(priv) priv_wif = encode_privkey(priv, 'wif_compressed', vbyte=priv_byte) if password: # pycrypto etc. must be installed or this will raise ImportError, hence inline import. from .bip38 import Bip38EncryptedPrivateKey priv_wif = str(Bip38EncryptedPrivateKey.encrypt(crypto, priv_wif, password)) compressed_pub = encode_pubkey(pub, 'hex_compressed') ret = { 'public': { 'hex_uncompressed': pub, 'hex': compressed_pub, 'address': pubtoaddr(compressed_pub, pub_byte) }, 'private': { 'wif': priv_wif } } if not password: # only these are valid when no bip38 password is supplied ret['private']['hex'] = encode_privkey(priv, 'hex_compressed', vbyte=priv_byte) ret['private']['hex_uncompressed'] = encode_privkey(priv, 'hex', vbyte=priv_byte) ret['private']['wif_uncompressed'] = encode_privkey(priv, 'wif', vbyte=priv_byte) return ret
def sign_tx(private_key, hex_data): public_address = pubtoaddr(privtopub(private_key)) pubkey = privtopub(private_key) split_data = hex_data.split("00ffffffff") input_stubs = split_data[:-1] output_stub = split_data[-1] pre_sig_script = '1976a914'+b58check_to_hex(public_address)+'88acffffffff' sig_stubs = [] for i in range(len(input_stubs)): signing_message = '' for j in range(i): signing_message += input_stubs[j]+'00ffffffff' signing_message += input_stubs[i] + pre_sig_script for k in range(i+1, len(input_stubs)): signing_message += input_stubs[k]+'00ffffffff' signing_message += output_stub+'01000000' hashed_message = hashlib.sha256(hashlib.sha256(signing_message.decode('hex')).digest()).digest() signingkey = ecdsa.SigningKey.from_string(b58check_to_hex(private_key).decode('hex'), curve=ecdsa.SECP256k1) SIG = binascii.hexlify(signingkey.sign_digest(hashed_message, sigencode=ecdsa.util.sigencode_der_canonize)) ScriptSig = hex(len(SIG+'01')/2)[2:] + SIG + '01' + hex(len(pubkey)/2)[2:] + pubkey ScriptLength = hex(len(ScriptSig)/2)[2:] sig_stub = ScriptLength+ScriptSig+'ffffffff' sig_stubs.append(sig_stub) bytes_ = '' for q in range(len(sig_stubs)): bytes_ += input_stubs[q]+sig_stubs[q] bytes_ += output_stub return bytes_
def foo(f): result.append(f.result()) if len(result) == len(futures): key = binascii.hexlify(xor(*result)) pub = bitcoin.pubtoaddr(bitcoin.privtopub(key)) if pub == _pub_key: print "Found passphrase: ", passphrase print key, "->", pub
def save(self, *args, **kwargs): created = not self.pk if created: self.public_key = privtopub(self.private_key) self.address = pubtoaddr(self.public_key) super().save(*args, **kwargs)
def foo(f): result.append(f.result()) if len(result) == len(futures): key = binascii.hexlify(xor(*result)) pub = bitcoin.pubtoaddr(bitcoin.privtopub(key)) if pub == _pub_key: print "Found passphrase: ", passphrase print key , "->", pub
def __init__(self, private_key=None, outputs=None, previous_n=0): if not private_key: self.private_key = bitcoin.electrum_privkey(current_app.config.get('BITCOIN_KEY_SEED'), previous_n+1) else: self.private_key = private_key self.public_key = bitcoin.privtopub(self.private_key) self.address = bitcoin.pubtoaddr(self.public_key) self.outputs = outputs self.created = datetime.datetime.utcnow()
def test_p2p_broadcast(setup_tx_notify): #listen up kids, dont do this to generate private #keys that hold real money, or else you'll be robbed src_privkey = random.getrandbits(256) src_privkey = btc.encode(src_privkey, 16, 64) + '01' src_addr = btc.privtoaddr(src_privkey, magicbyte=get_p2pk_vbyte()) dst_addr = btc.pubtoaddr('03' + btc.encode(random.getrandbits(256), 16), get_p2pk_vbyte()) jm_single().bc_interface.rpc('importaddress', [src_addr, "", False]) jm_single().bc_interface.rpc('importaddress', [dst_addr, "", False]) jm_single().bc_interface.rpc('generatetoaddress', [1, src_addr]) jm_single().bc_interface.rpc('generate', [101]) src_utxos = jm_single().bc_interface.rpc('listunspent', [0, 500, [src_addr]]) inputs = [{ 'output': src_utxos[0]['txid'] + ':' + str(src_utxos[0]['vout']) }] miner_fee = 10000 outs = [{ 'address': dst_addr, 'value': int(src_utxos[0]['amount'] * 1e8) - miner_fee }] tx = btc.mktx(inputs, outs) tx = btc.sign(tx, 0, src_privkey) bad_tx = random.getrandbits(len(tx) * 4) bad_tx = btc.encode(bad_tx, 16, len(tx)) utxo_before = jm_single().bc_interface.rpc('listunspent', [0, 500, [dst_addr]]) #jm_single().bc_interface.rpc('sendrawtransaction', [tx]) pushed = tor_broadcast_tx(tx, None, 'regtest', remote_hostport=('localhost', 18444)) assert pushed pushed = tor_broadcast_tx(tx, None, 'regtest', remote_hostport=('localhost', 18444)) assert not pushed #node should already have the same tx, reject pushed = tor_broadcast_tx(bad_tx, None, 'regtest', remote_hostport=('localhost', 18444)) assert not pushed #bad tx should be rejected jm_single().bc_interface.rpc('generate', [1]) utxo_after = jm_single().bc_interface.rpc('listunspent', [0, 500, [dst_addr]]) return len(utxo_after) - 1 == len(utxo_before)
def __init__(self, private_key=None, outputs=None, previous_n=0): if not private_key: self.private_key = bitcoin.electrum_privkey( current_app.config.get('BITCOIN_KEY_SEED'), previous_n + 1) else: self.private_key = private_key self.public_key = bitcoin.privtopub(self.private_key) self.address = bitcoin.pubtoaddr(self.public_key) self.outputs = outputs self.created = datetime.datetime.utcnow()
def address(args): c = 1 if args.change else 0 if (args.index < 0): unspents = bitcoin.BlockchainInfo.unspent_xpub(args.xpub) index = check_outputs_max_index(unspents, c) else: index = args.index address = bitcoin.pubtoaddr(bitcoin.bip32_descend(args.xpub, c, index)) print(address)
def address(args): c = 1 if args.change else 0 if args.index < 0: unspents = bitcoin.BlockchainInfo.unspent_xpub(args.xpub) index = check_outputs_max_index(unspents, c) else: index=args.index address = bitcoin.pubtoaddr(bitcoin.bip32_descend(args.xpub, c, index)) print(address)
def private_key_to_address(self, pk): """ Convert a private key (in hex format) into an address. """ pub = privtopub(pk) pub_byte, priv_byte = get_magic_bytes(self.crypto) if priv_byte >= 128: priv_byte -= 128 #pybitcointools bug return pubtoaddr(pub, pub_byte)
def getAddressesFromXPUB(xpub, i=10): addressList = [] pub0 = bitcoin.bip32_ckd(xpub, 0) for i in range (0, i): publicKey = bitcoin.bip32_ckd(pub0, i) hexKey = bitcoin.encode_pubkey(bitcoin.bip32_extract_key(publicKey), 'hex_compressed') address_fromPub = bitcoin.pubtoaddr(hexKey) addressList.append(address_fromPub) return addressList
def get_next_address(send_job): if 'addresses' in send_job: this_index = send_job['index'] send_job['index'] = (send_job['index'] + 1) % len(send_job['addresses']) return send_job['addresses'][this_index] elif 'xpub' in send_job: send_job['index'] += 1 return btc.pubtoaddr(btc.bip32_extract_key(btc.bip32_ckd( send_job['xpub'], send_job['index']-1)), get_p2pk_vbyte()) else: assert False
def real(chat_id=chat_id, coin=coin): if coin == 'btc': #priv, addr = generate_wallet("Bitcoin") priv = pbt.random_key() pub = pbt.privtopub(priv) addr = pbt.pubtoaddr(pub) addr = self.record_to_addressdb(chat_id, coin, addr, priv) elif coin == 'ltc': #priv, addr = generate_wallet("Litecoin") priv, addr = self.ltcgen.generate() addr = self.record_to_addressdb(chat_id, coin, addr, priv) return addr
def donation_address(reusable_donation_pubkey=None): if not reusable_donation_pubkey: reusable_donation_pubkey = ('02be838257fbfddabaea03afbb9f16e852' '9dfe2de921260a5c46036d97b5eacf2a') sign_k = binascii.hexlify(os.urandom(32)) c = btc.sha256(btc.multiply(sign_k, reusable_donation_pubkey, True)) sender_pubkey = btc.add_pubkeys([reusable_donation_pubkey, btc.privtopub(c+'01', True)], True) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) log.info('sending coins to ' + sender_address) return sender_address, sign_k
def validate_sig(sig, msg, address, type="transaction"): try: pubkey = ecdsa_recover(msg, sig) except: raise InvalidSignature("Can't recover pubkey from %s signature" % type) valid_sig = ecdsa_verify(msg, sig, pubkey) valid_address = pubtoaddr(pubkey) == address if not valid_sig or not valid_address: raise InvalidSignature("%s signature not valid" % type.title()) return True
def warp(passphrase, salt=""): s1 = scrypt.hash(passphrase + "\x01", salt + "\x01", N=2**18, r=8, p=1, buflen=32) s2 = pbkdf2(passphrase + "\x02", salt=salt + "\x02", keylen=32, rounds=2**16, prf="hmac-sha256") key = binascii.hexlify(xor(s1, s2)) return key, bitcoin.pubtoaddr(bitcoin.privtopub(key))
def get_addresses(cls, data, script_type): candidate_nonstandard = False try: if script_type == "pubkeyhash" and len(data['s'][2]) == 40: return [hex_to_b58check(data['s'][2].encode('utf-8'), data['p']['pub'])] elif script_type == "scripthash" and len(data['s'][1]) == 40: return [hex_to_b58check(data['s'][1].encode('utf-8'), data['p']['p2sh'])] elif script_type == "multisig": addrs = [] for i in range(1, int(SCRIPTS[data['s'][-2]])+1): if len(data['s'][i]) not in (130, 66, 78): candidate_nonstandard = True if isValidPubKey(data['s'][i]): k = pubtoaddr(data['s'][i].encode('utf-8')) addrs.append(k) if candidate_nonstandard: raise VoutDecoderException('','','') return addrs elif script_type == "pubkey": return [pubtoaddr(data['s'][0].encode('utf-8'), 0x00)] if isValidPubKey(data['s'][0]) else [] except (AttributeError, TypeError): raise VoutDecoderException('','','') return []
def generate_keys(): timestr = time.strftime('%H%M%S') # Open file that will contain generated keys keysfile_name = 'random_keys_' + timestr + '.txt' keysfile = open(keysfile_name, 'w') for i in range(1000): privkey = random_key() pubkey = privtopub(privkey) pubaddr = pubtoaddr(pubkey) keysfile.write(pubaddr + '|' + privkey + '|' + pubkey) keysfile.write('\n') keysfile.close()
def read_wallet(): """ Gets wallet details from disk Returns: priv, pub, addr (str, str, str): private key, public key, address """ fname = "{dir}wallets/{name}.txt".format(dir=settings.user_dir, name=settings.ACCOUNT_NAME) with open(fname, "r") as text_file: priv = str(text_file.read()) pub = bitcoin.privtopub(priv) addr = bitcoin.pubtoaddr(pub) return priv, pub, addr
def bip38_decrypt(encrypted_privkey, passphrase, wif=False): """ BIP0038 non-ec-multiply decryption. Returns hex privkey. """ passphrase = normalize('NFC', unicode(passphrase)) if is_py2: passphrase = passphrase.encode('utf8') d = unhexlify(changebase(encrypted_privkey, 58, 16, 86)) d = d[2:] flagbyte = d[0:1] d = d[1:] # respect flagbyte, return correct pair if flagbyte == b'\xc0': compressed = False if flagbyte == b'\xe0': compressed = True addresshash = d[0:4] d = d[4:-4] key = scrypt.hash(passphrase,addresshash, 16384, 8, 8) derivedhalf1 = key[0:32] derivedhalf2 = key[32:64] encryptedhalf1 = d[0:16] encryptedhalf2 = d[16:32] aes = AES.new(derivedhalf2) decryptedhalf2 = aes.decrypt(encryptedhalf2) decryptedhalf1 = aes.decrypt(encryptedhalf1) priv = decryptedhalf1 + decryptedhalf2 priv = unhexlify('%064x' % (long(hexlify(priv), 16) ^ long(hexlify(derivedhalf1), 16))) pub = privtopub(priv) if compressed: pub = encode_pubkey(pub,'hex_compressed') addr = pubtoaddr(pub) if is_py2: ascii_key = addr else: ascii_key = bytes(addr,'ascii') if sha256(sha256(ascii_key).digest()).digest()[0:4] != addresshash: raise Exception('Bip38 password decrypt failed: Wrong password?') else: formatt = 'wif' if wif else 'hex' if compressed: return encode_privkey(priv, formatt + '_compressed') else: return encode_privkey(priv, formatt)
def donation_address(tx, wallet): from bitcoin.main import multiply, G, deterministic_generate_k, add_pubkeys reusable_donation_pubkey = ('02be838257fbfddabaea03afbb9f16e852' '9dfe2de921260a5c46036d97b5eacf2a') privkey = wallet.get_key_from_addr(wallet.get_new_addr(0, 0)) msghash = btc.bin_txhash(tx, btc.SIGHASH_ALL) # generate unpredictable k global sign_k sign_k = deterministic_generate_k(msghash, privkey) c = btc.sha256(multiply(reusable_donation_pubkey, sign_k)) sender_pubkey = add_pubkeys(reusable_donation_pubkey, multiply(G, c)) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) log.debug('sending coins to ' + sender_address) return privkey, sender_address
def donation_address(cjtx, wallet): privkey = wallet.get_key_from_addr(wallet.get_new_addr(0,0)) reusable_donation_pubkey = '02be838257fbfddabaea03afbb9f16e8529dfe2de921260a5c46036d97b5eacf2a' global sign_k import os import binascii sign_k = os.urandom(32) log.debug("Using the following nonce value: "+binascii.hexlify(sign_k)) c = btc.sha256(btc.multiply(binascii.hexlify(sign_k), reusable_donation_pubkey, True)) sender_pubkey = btc.add_pubkeys([reusable_donation_pubkey, btc.privtopub(c+'01', True)], True) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) log.debug('sending coins to ' + sender_address) return privkey, sender_address
def address(args): c = 1 if args.change else 0 if (args.index < 0): unspents = bitcoin.BlockchainInfo.unspent_xpub(args.xpub) index = check_outputs_max_index(unspents, c) else: index = args.index if (coin_arg_parse(args.coin) != coin_arg_parse('BTC')): print("Error: not known how to build address for coin \"" + args.coin + "\"") address = bitcoin.pubtoaddr(bitcoin.bip32_descend(args.xpub, c, index)) print(address)
def send(args): if (len(args.outputs) % 2 != 0): raise Exception( "When sending, there must be an even number of arguments for the outputs (address,price)" ) unspents = bitcoin.BlockchainInfo.unspent_xpub(args.xpub) def btctosatoshi(vs): return int(float(vs) * 100000000.0) fee = btctosatoshi(args.fee) if (fee < 0): fee = int( 0.0001 * 100000000 ) #todo do something to estimated fee...make it negative or something though... DONT outaddrval = [(args.outputs[2 * i], btctosatoshi(args.outputs[2 * i + 1])) for i in range(len(args.outputs) // 2)] outtotalval = sum([o[1] for o in outaddrval]) changeindex = check_outputs_max_index(unspents, 1) changeaddress = bitcoin.pubtoaddr( bitcoin.bip32_descend(args.xpub, 1, changeindex)) unspents = bitcoin.select(unspents, outtotalval + fee) #unspents cull using outtotalval unspenttotalval = sum([u['value'] for u in unspents]) changeamount = unspenttotalval - (outtotalval + abs(fee)) if (changeamount < 0): raise Exception( "There is unlikely to be enough unspent outputs to cover the transaction and fees" ) out = {} outs = outaddrval if (changeamount > 0): outs += [[changeaddress, changeamount]] #print(unspents) #print(outs) otx = [{'address': o[0], 'value': o[1]} for o in outs] tx = bitcoin.mktx(unspents, otx) #compute all the underlying addresses and pubkeys into a string hash #estimate the fee #build the transaction out['tx'] = tx u['xpub']['value'] = u['value'] out['keys'] = dict([(u['output'], u['xpub']) for u in unspents]) #print(bitcoin.deserialize(tx)) json.dump(out, sys.stdout)
def validate_peer_registration(reg, now=None): ts = dateutil.parser.parse(reg['timestamp']) validate_timestamp(ts, now=now) to_sign = "{domain}{payout_address}{timestamp}".format(**reg) try: pubkey = ecdsa_recover(to_sign, reg['signature']) except: raise InvalidSignature("Can't recover pubkey from signature") valid_address = pubtoaddr(pubkey) == reg['payout_address'] valid_sig = ecdsa_verify(to_sign, reg['signature'], pubkey) if not valid_sig or not valid_address: raise InvalidSignature("Invalid Signature") return True
def __init__(self, bot, priv): self.bot = bot self.ttl = 35 * 60 pub = bitcoin.privtopub(priv) addr = bitcoin.pubtoaddr(pub) self.cards = [{ "name": name, "number": number } for name, number in zip(bot.const["banks"], os.environ.get("CARD_NUMBER").split(";"))] self.private = priv self.public = pub self.address = addr self.comission = bot.const["comission"]
def spend(self, owner): assert isinstance(owner, (str, bytes)) assert len(owner) == 20 # Sign it, so it can be accepted by an address messageHash = utils.sha3(owner + self._pubkey) V, R, S = b.ecdsa_raw_sign(messageHash, self._seckey) recoveredPublicKey = b.ecdsa_raw_recover(messageHash, (V, R, S)) assert b.pubtoaddr(recoveredPublicKey) == b.privtoaddr(self._seckey) # Correctly encoded return ", ".join([ "\"0x%s\"" % (hexlify(self._pubkey), ), "%d" % (V, ), "\"0x%064X\"" % (R, ), "\"0x%064X\"" % (S, ), ])
def verify_unsigned_tx(self, txd): tx_utxo_set = set(ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) for ins in txd['ins']) # complete authentication: check the tx input uses the authing pubkey input_utxo_data = jm_single().bc_interface.query_utxo_set( list(tx_utxo_set)) if None in input_utxo_data: return False, 'some utxos already spent or not confirmed yet' input_addresses = [u['address'] for u in input_utxo_data] if btc.pubtoaddr( self.i_utxo_pubkey, get_p2pk_vbyte()) not in input_addresses: return False, "authenticating bitcoin address is not contained" my_utxo_set = set(self.utxos.keys()) if not tx_utxo_set.issuperset(my_utxo_set): return False, 'my utxos are not contained' my_total_in = sum([va['value'] for va in self.utxos.values()]) self.real_cjfee = calc_cj_fee( self.ordertype, self.cjfee, self.cj_amount) expected_change_value = ( my_total_in - self.cj_amount - self.txfee + self.real_cjfee) log.debug('potentially earned = {}'.format( self.real_cjfee - self.txfee)) log.debug('mycjaddr, mychange = {}, {}'.format( self.cj_addr, self.change_addr)) times_seen_cj_addr = 0 times_seen_change_addr = 0 for outs in txd['outs']: addr = btc.script_to_address(outs['script'], get_p2pk_vbyte()) if addr == self.cj_addr: times_seen_cj_addr += 1 if outs['value'] != self.cj_amount: return False, 'Wrong cj_amount. I expect ' + str( self.cj_amount) if addr == self.change_addr: times_seen_change_addr += 1 if outs['value'] != expected_change_value: return False, 'wrong change, i expect ' + str( expected_change_value) if times_seen_cj_addr != 1 or times_seen_change_addr != 1: fmt = ('cj or change addr not in tx ' 'outputs once, #cjaddr={}, #chaddr={}').format return False, (fmt(times_seen_cj_addr, times_seen_change_addr)) return True, None
def verify_unsigned_tx(self, txd): tx_utxo_set = set(ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index']) for ins in txd['ins']) # complete authentication: check the tx input uses the authing pubkey input_utxo_data = jm_single().bc_interface.query_utxo_set( list(tx_utxo_set)) if None in input_utxo_data: return False, 'some utxos already spent or not confirmed yet' input_addresses = [u['address'] for u in input_utxo_data] if btc.pubtoaddr(self.i_utxo_pubkey, get_p2pk_vbyte()) not in input_addresses: return False, "authenticating bitcoin address is not contained" my_utxo_set = set(self.utxos.keys()) if not tx_utxo_set.issuperset(my_utxo_set): return False, 'my utxos are not contained' my_total_in = sum([va['value'] for va in self.utxos.values()]) self.real_cjfee = calc_cj_fee(self.ordertype, self.cjfee, self.cj_amount) expected_change_value = (my_total_in - self.cj_amount - self.txfee + self.real_cjfee) log.debug('potentially earned = {}'.format(self.real_cjfee - self.txfee)) log.debug('mycjaddr, mychange = {}, {}'.format(self.cj_addr, self.change_addr)) times_seen_cj_addr = 0 times_seen_change_addr = 0 for outs in txd['outs']: addr = btc.script_to_address(outs['script'], get_p2pk_vbyte()) if addr == self.cj_addr: times_seen_cj_addr += 1 if outs['value'] != self.cj_amount: return False, 'Wrong cj_amount. I expect ' + str( self.cj_amount) if addr == self.change_addr: times_seen_change_addr += 1 if outs['value'] != expected_change_value: return False, 'wrong change, i expect ' + str( expected_change_value) if times_seen_cj_addr != 1 or times_seen_change_addr != 1: fmt = ('cj or change addr not in tx ' 'outputs once, #cjaddr={}, #chaddr={}').format return False, (fmt(times_seen_cj_addr, times_seen_change_addr)) return True, None
def donation_address(tx, wallet): from bitcoin.main import multiply, G, deterministic_generate_k, add_pubkeys reusable_donation_pubkey = ('02be838257fbfddabaea03afbb9f16e852' '9dfe2de921260a5c46036d97b5eacf2a') privkey = wallet.get_key_from_addr(wallet.get_new_addr(0,0)) msghash = btc.bin_txhash(tx, btc.SIGHASH_ALL) # generate unpredictable k global sign_k sign_k = deterministic_generate_k(msghash, privkey) c = btc.sha256(multiply(reusable_donation_pubkey, sign_k)) sender_pubkey = add_pubkeys( reusable_donation_pubkey, multiply( G, c)) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) log.debug('sending coins to ' + sender_address) return privkey, sender_address
def validate_transaction(tx, ledger=None, min_fee=0.01, now=None): """ Validates that the passed in transaction object is valid in terms of cryptography. UTXO validation does not happen here. `ledger` is a callable that returns the address's balance and last spend timestamp. """ ts = dateutil.parser.parse(tx['timestamp']) out_total, out_msg = _process_outputs(tx['outputs'], ts) validate_timestamp(ts, now=now) in_total = 0 for i, input in enumerate(tx['inputs']): address, amount, sig = input amount = _cut_to_8(amount) if amount <= 0: raise InvalidAmounts("Input %s can't be zero or negative" % i) message = "%s%s%s" % (address, amount, out_msg) in_total += amount try: pubkey = ecdsa_recover(message, sig) except: raise InvalidSignature("Signature %s not valid" % i) if ledger: address_balance, last_spend = ledger(address) delt = datetime.timedelta(seconds=PROPAGATION_WINDOW_SECONDS) if last_spend + delt > ts: raise InvalidTransaction("Input too young") if address_balance < amount: raise InvalidAmounts("Not enough balance in %s" % address) valid_sig = ecdsa_verify(message, sig, pubkey) valid_address = pubtoaddr(pubkey) == address if not valid_sig or not valid_address: raise InvalidSignature("Signature %s not valid" % i) if in_total < out_total: raise InvalidAmounts("Input amount does not exceed output amount") fee = in_total - out_total if fee < min_fee: raise InvalidFee("Fee of %.8f below min fee of %.8f" % (fee, min_fee)) return True
def donation_address(cjtx, wallet): privkey = wallet.get_key_from_addr(wallet.get_new_addr(0, 0)) reusable_donation_pubkey = '02be838257fbfddabaea03afbb9f16e8529dfe2de921260a5c46036d97b5eacf2a' global sign_k import os import binascii sign_k = os.urandom(32) log.debug("Using the following nonce value: " + binascii.hexlify(sign_k)) c = btc.sha256( btc.multiply(binascii.hexlify(sign_k), reusable_donation_pubkey, True)) sender_pubkey = btc.add_pubkeys( [reusable_donation_pubkey, btc.privtopub(c + '01', True)], True) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) log.debug('sending coins to ' + sender_address) return privkey, sender_address
def init_code(self): import bitcoin for schema in self: x=schema.registry_pb pbmsg=base64.b64decode( x ) pbr = Registry() pbr.ParseFromString( pbmsg ) for m in pbr.models: self.env.cr.execute("select id from %s where code is Null"%m._table) for rec in self.env.cr.fetchall(): id_=rec[0] secret_key = bitcoin.random_key() pub_key = bitcoin.privtopub(secret_key) code = bitcoin.pubtoaddr( pub_key ) sql_update="update %s set " % m._table self.env.cr.execute( sql_update+"code=%s,secret_key=%s where id=%s", (code,secret_key,id_) )
def generate_key(secret, testnet=111): if os.path.isfile(keyfile): print "ERR: another key under use. Dismiss before generate anew" print "exiting, no operation" exit(-1) priv = btc.sha256(secret) pub = btc.privtopub(priv) addr = btc.pubtoaddr( pub, 111 if testnet else None) #111 optional, generates for testnet print 'new wallet address is', addr print 'we are using', "testnet" if testnet else "mainnet" print 'fill this address with some coins to pay fees' with open(keyfile, 'w') as f: f.write(priv) print 'key is saved in', keyfile
def generate_keypair(crypto, seed, password=None): """ Generate a private key and publickey for any currency, given a seed. That seed can be random, or a brainwallet phrase. """ if crypto in ['eth', 'etc']: raise CurrencyNotSupported("Ethereums not yet supported") pub_byte, priv_byte = get_magic_bytes(crypto) priv = sha256(seed) pub = privtopub(priv) priv_wif = encode_privkey(priv, 'wif_compressed', vbyte=priv_byte) if password: # pycrypto etc. must be installed or this will raise ImportError, hence inline import. from .bip38 import Bip38EncryptedPrivateKey priv_wif = str( Bip38EncryptedPrivateKey.encrypt(crypto, priv_wif, password)) compressed_pub = encode_pubkey(pub, 'hex_compressed') ret = { 'public': { 'hex_uncompressed': pub, 'hex': compressed_pub, 'address': pubtoaddr(compressed_pub, pub_byte) }, 'private': { 'wif': priv_wif } } if not password: # only these are valid when no bip38 password is supplied ret['private']['hex'] = encode_privkey(priv, 'hex_compressed', vbyte=priv_byte) ret['private']['hex_uncompressed'] = encode_privkey(priv, 'hex', vbyte=priv_byte) ret['private']['wif_uncompressed'] = encode_privkey(priv, 'wif', vbyte=priv_byte) return ret
def donation_address(cjtx): reusable_donation_pubkey = '02be838257fbfddabaea03afbb9f16e8529dfe2de921260a5c46036d97b5eacf2a' donation_utxo_data = cjtx.input_utxos.iteritems().next() global donation_utxo donation_utxo = donation_utxo_data[0] privkey = cjtx.wallet.get_key_from_addr(donation_utxo_data[1]['address']) tx = btc.mktx(cjtx.utxo_tx, cjtx.outputs) #tx without our inputs and outputs #address = privtoaddr(privkey) #signing_tx = signature_form(tx, 0, mk_pubkey_script(address), SIGHASH_ALL) msghash = btc.bin_txhash(tx, btc.SIGHASH_ALL) #generate unpredictable k global sign_k sign_k = btc.deterministic_generate_k(msghash, privkey) c = btc.sha256(btc.multiply(reusable_donation_pubkey, sign_k)) sender_pubkey = btc.add_pubkeys(reusable_donation_pubkey, btc.multiply(btc.G, c)) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) debug('sending coins to ' + sender_address) return sender_address
def bip38_encrypt(privkey, passphrase): """ BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey. """ privformat = get_privkey_format(privkey) if privformat in ['wif_compressed','hex_compressed']: compressed = True flagbyte = b'\xe0' if privformat == 'wif_compressed': privkey = encode_privkey(privkey,'hex_compressed') privformat = get_privkey_format(privkey) if privformat in ['wif', 'hex']: compressed = False flagbyte = b'\xc0' if privformat == 'wif': privkey = encode_privkey(privkey,'hex') privformat = get_privkey_format(privkey) pubkey = privtopub(privkey) addr = pubtoaddr(pubkey) passphrase = normalize('NFC', unicode(passphrase)) if is_py2: ascii_key = addr passphrase = passphrase.encode('utf8') else: ascii_key = bytes(addr,'ascii') salt = sha256(sha256(ascii_key).digest()).digest()[0:4] key = scrypt.hash(passphrase, salt, 16384, 8, 8) derivedhalf1, derivedhalf2 = key[:32], key[32:] aes = AES.new(derivedhalf2) encryptedhalf1 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[0:32], 16) ^ long(hexlify(derivedhalf1[0:16]), 16)))) encryptedhalf2 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[32:64], 16) ^ long(hexlify(derivedhalf1[16:32]), 16)))) payload = b'\x01' + b'\x42' + flagbyte + salt + encryptedhalf1 + encryptedhalf2 checksum = sha256(sha256(payload).digest()).digest()[:4] # b58check for encrypted privkey privatkey = hexlify(payload + checksum).decode('ascii') return changebase(privatkey, 16, 58)
def verify_unsigned_tx(self, txd): tx_utxo_set = set([ins['outpoint']['hash'] + ':' \ + str(ins['outpoint']['index']) for ins in txd['ins']]) #complete authentication: check the tx input uses the authing pubkey input_utxo_data = common.bc_interface.query_utxo_set(list(tx_utxo_set)) input_addresses = [u['address'] for u in input_utxo_data] if btc.pubtoaddr(self.i_utxo_pubkey, get_addr_vbyte())\ not in input_addresses: return False, "authenticating bitcoin address is not contained" my_utxo_set = set(self.utxos.keys()) wallet_utxos = set(self.maker.wallet.unspent) if not tx_utxo_set.issuperset(my_utxo_set): return False, 'my utxos are not contained' if not wallet_utxos.issuperset(my_utxo_set): return False, 'my utxos already spent' my_total_in = sum([va['value'] for va in self.utxos.values()]) self.real_cjfee = calc_cj_fee(self.ordertype, self.cjfee, self.cj_amount) expected_change_value = (my_total_in - self.cj_amount - self.txfee + self.real_cjfee) debug('earned = ' + str(self.real_cjfee - self.txfee)) debug('mycjaddr, mychange = ' + self.cj_addr + ', ' + self.change_addr) times_seen_cj_addr = 0 times_seen_change_addr = 0 for outs in txd['outs']: addr = btc.script_to_address(outs['script'], get_addr_vbyte()) if addr == self.cj_addr: times_seen_cj_addr += 1 if outs['value'] != self.cj_amount: return False, 'Wrong cj_amount. I expect ' + str(cj_amount) if addr == self.change_addr: times_seen_change_addr += 1 if outs['value'] != expected_change_value: return False, 'wrong change, i expect ' + str(expected_change_value) if times_seen_cj_addr != 1 or times_seen_change_addr != 1: return False, ('cj or change addr not in tx outputs once, #cjaddr=' + str(times_seen_cj_addr) + ', #chaddr=' + str(times_seen_change_addr)) return True, None
def donation_address(cjtx): from bitcoin.main import multiply, G, deterministic_generate_k, add_pubkeys reusable_donation_pubkey = ('02be838257fbfddabaea03afbb9f16e852' '9dfe2de921260a5c46036d97b5eacf2a') donation_utxo_data = cjtx.input_utxos.iteritems().next() global donation_utxo donation_utxo = donation_utxo_data[0] privkey = cjtx.wallet.get_key_from_addr(donation_utxo_data[1]['address']) # tx without our inputs and outputs tx = btc.mktx(cjtx.utxo_tx, cjtx.outputs) msghash = btc.bin_txhash(tx, btc.SIGHASH_ALL) # generate unpredictable k global sign_k sign_k = deterministic_generate_k(msghash, privkey) c = btc.sha256(multiply(reusable_donation_pubkey, sign_k)) sender_pubkey = add_pubkeys( reusable_donation_pubkey, multiply( G, c)) sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte()) log.debug('sending coins to ' + sender_address) return sender_address
def send(args): if len(args.outputs) % 2 != 0: raise Exception("When sending, there must be an even number of arguments " + "for the outputs (address, price)") unspents = bitcoin.BlockchainInfo.unspent_xpub(args.xpub) def btctosatoshi(vs): return int(float(vs)*100000000.0) fee = btctosatoshi(args.fee) if fee < 0: fee = int(0.0001*100000000) #todo do something to estimated fee...make it negative or something though... DONT outaddrval = [(args.outputs[2*i],btctosatoshi(args.outputs[2*i+1])) for i in range(len(args.outputs)//2)] outtotalval = sum([o[1] for o in outaddrval]) changeindex = check_outputs_max_index(unspents,1) changeaddress = bitcoin.pubtoaddr(bitcoin.bip32_descend(args.xpub, 1, changeindex)) unspents = bitcoin.select(unspents, outtotalval+fee) #unspents cull using outtotalval unspenttotalval = sum([u['value'] for u in unspents]) changeamount = unspenttotalval - (outtotalval + abs(fee)) if changeamount < 0: raise Exception("There is unlikely to be enough unspent outputs to cover the transaction and fees") out = {} outs = outaddrval if changeamount > 0: outs += [[changeaddress, changeamount]] #print(unspents) #print(outs) otx = [{'address':o[0], 'value':o[1]} for o in outs] tx = bitcoin.mktx(unspents, otx) #compute all the underlying addresses and pubkeys into a string hash #estimate the fee #build the transaction out['tx'] = tx out['keys'] = dict([(u['output'], u['xpub']) for u in unspents]) #print(bitcoin.deserialize(tx)) json.dump(out, sys.stdout)
def op_init(opt, stack): DEPLOYMENT_NAME=opt.deployment_name dbname=stack.pop() conn,tp=get_connection(opt, dbname) assert tp=='pg' cr=conn.cursor() pb_fn = os.path.join(opt.pbdir, DEPLOYMENT_NAME + '.pb' ) pbr = Registry() pbr.ParseFromString( file(pb_fn).read() ) import bitcoin for m in pbr.models: cr.execute("select id from %s where code is Null"%m._table) for rec in cr.fetchall(): id_=rec[0] secret_key = bitcoin.random_key() pub_key = bitcoin.privtopub(secret_key) code = bitcoin.pubtoaddr( pub_key ) sql_update="update %s set " % m._table cr.execute( sql_update+"code=%s,secret_key=%s where id=%s", (code,secret_key,id_) ) cr.close() conn.commit()
def main(): ''' Our main function. ''' if os.path.isfile(SECRET_FILE): print('It seems you have already created the keys.') return 1 priv = bitcoin.encode_privkey(bitcoin.random_key(), 'wif') with open(SECRET_FILE, 'w') as secret_file: secret_file.write(priv) pub = bitcoin.privtopub(priv) with open(PUBLIC_FILE, 'w') as public_file: public_file.write(pub) address = bitcoin.pubtoaddr(pub, 0) with open(ADDRESS_FILE, 'w') as addres_file: addres_file.write(address) print('Generated {} and {}'.format(SECRET_FILE, PUBLIC_FILE)) print('Keep {} safe and back it up. Hint: Use scrypt to encrypt the key.'.format(SECRET_FILE)) print('Send BTC to {}'.format(address)) return 0
def test_donation_address(setup_donations, amount): wallets = make_wallets(1, wallet_structures=[[1,1,1,0,0]], mean_amt=0.5) wallet = wallets[0]['wallet'] jm_single().bc_interface.sync_wallet(wallet) #make a rdp from a simple privkey rdp_priv = "\x01"*32 reusable_donation_pubkey = binascii.hexlify(secp256k1.PrivateKey( privkey=rdp_priv, raw=True, ctx=btc.ctx).pubkey.serialize()) dest_addr, sign_k = donation_address(reusable_donation_pubkey) print dest_addr jm_single().bc_interface.rpc('importaddress', [dest_addr, '', False]) ins_full = wallet.unspent total = sum(x['value'] for x in ins_full.values()) ins = ins_full.keys() output_addr = wallet.get_new_addr(1, 1) fee_est = 10000 outs = [{'value': amount, 'address': dest_addr}, {'value': total - amount - fee_est, 'address': output_addr}] tx = btc.mktx(ins, outs) de_tx = btc.deserialize(tx) for index, ins in enumerate(de_tx['ins']): utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index']) addr = ins_full[utxo]['address'] priv = wallet.get_key_from_addr(addr) priv = binascii.unhexlify(priv) usenonce = binascii.unhexlify(sign_k) if index == 0 else None if index == 0: log.debug("Applying rdp to input: " + str(ins)) tx = btc.sign(tx, index, priv, usenonce=usenonce) #pushtx returns False on any error push_succeed = jm_single().bc_interface.pushtx(tx) if push_succeed: log.debug(btc.txhash(tx)) else: assert False #Role of receiver: regenerate the destination private key, #and address, from the nonce of the first input; check it has #received the coins. detx = btc.deserialize(tx) first_utxo_script = detx['ins'][0]['script'] sig, pub = btc.deserialize_script(first_utxo_script) log.debug(sig) sig = binascii.unhexlify(sig) kGlen = ord(sig[3]) kG = sig[4:4+kGlen] log.debug(binascii.hexlify(kG)) if kG[0] == "\x00": kG = kG[1:] #H(rdp private key * K) + rdp should be ==> dest addr #Open issue: re-introduce recovery without ECC shenanigans #Just cheat by trying both signs for pubkey coerced_kG_1 = "02" + binascii.hexlify(kG) coerced_kG_2 = "03" + binascii.hexlify(kG) for coerc in [coerced_kG_1, coerced_kG_2]: c = btc.sha256(btc.multiply(binascii.hexlify(rdp_priv), coerc, True)) pub_check = btc.add_pubkeys([reusable_donation_pubkey, btc.privtopub(c+'01', True)], True) addr_check = btc.pubtoaddr(pub_check, get_p2pk_vbyte()) log.debug("Found checked address: " + addr_check) if addr_check == dest_addr: time.sleep(3) received = jm_single().bc_interface.get_received_by_addr( [dest_addr], None)['data'][0]['balance'] assert received == amount return assert False
def recv_txio(self, nick, utxo_list, cj_pub, change_addr): if nick not in self.nonrespondants: log.debug(('recv_txio => nick={} not in ' 'nonrespondants {}').format(nick, self.nonrespondants)) return self.utxos[nick] = utxo_list utxo_data = jm_single().bc_interface.query_utxo_set(self.utxos[nick]) if None in utxo_data: log.debug(('ERROR outputs unconfirmed or already spent. ' 'utxo_data={}').format(pprint.pformat(utxo_data))) # when internal reviewing of makers is created, add it here to # immediately quit; currently, the timeout thread suffices. return total_input = sum([d['value'] for d in utxo_data]) real_cjfee = calc_cj_fee(self.active_orders[nick]['ordertype'], self.active_orders[nick]['cjfee'], self.cj_amount) change_amount = (total_input - self.cj_amount - self.active_orders[nick]['txfee'] + real_cjfee) # certain malicious and/or incompetent liquidity providers send # inputs totalling less than the coinjoin amount! this leads to # a change output of zero satoshis, so the invalid transaction # fails harmlessly; let's fail earlier, with a clear message. if change_amount < jm_single().DUST_THRESHOLD: fmt = ('ERROR counterparty requires sub-dust change. nick={}' 'totalin={:d} cjamount={:d} change={:d}').format log.debug(fmt(nick, total_input, self.cj_amount, change_amount)) return # timeout marks this maker as nonresponsive self.outputs.append({'address': change_addr, 'value': change_amount}) fmt = ('fee breakdown for {} totalin={:d} ' 'cjamount={:d} txfee={:d} realcjfee={:d}').format log.debug(fmt(nick, total_input, self.cj_amount, self.active_orders[nick]['txfee'], real_cjfee)) cj_addr = btc.pubtoaddr(cj_pub, get_p2pk_vbyte()) self.outputs.append({'address': cj_addr, 'value': self.cj_amount}) self.cjfee_total += real_cjfee self.maker_txfee_contributions += self.active_orders[nick]['txfee'] self.nonrespondants.remove(nick) if len(self.nonrespondants) > 0: log.debug('nonrespondants = ' + str(self.nonrespondants)) return log.debug('got all parts, enough to build a tx') self.nonrespondants = list(self.active_orders.keys()) my_total_in = sum([va['value'] for u, va in self.input_utxos.iteritems()]) if self.my_change_addr: #Estimate fee per choice of next/3/6 blocks targetting. estimated_fee = estimate_tx_fee(len(sum( self.utxos.values(),[])), len(self.outputs)+2) log.debug("Based on initial guess: "+str( self.total_txfee)+", we estimated a fee of: "+str(estimated_fee)) #reset total self.total_txfee = estimated_fee my_txfee = max(self.total_txfee - self.maker_txfee_contributions, 0) my_change_value = ( my_total_in - self.cj_amount - self.cjfee_total - my_txfee) #Since we could not predict the maker's inputs, we may end up needing #too much such that the change value is negative or small. Note that #we have tried to avoid this based on over-estimating the needed amount #in SendPayment.create_tx(), but it is still a possibility if one maker #uses a *lot* of inputs. if self.my_change_addr and my_change_value <= 0: raise ValueError("Calculated transaction fee of: "+str( self.total_txfee)+" is too large for our inputs;Please try again.") elif self.my_change_addr and my_change_value <= jm_single().DUST_THRESHOLD: log.debug("Dynamically calculated change lower than dust: "+str( my_change_value)+"; dropping.") self.my_change_addr = None my_change_value = 0 log.debug('fee breakdown for me totalin=%d my_txfee=%d makers_txfee=%d cjfee_total=%d => changevalue=%d' % (my_total_in, my_txfee, self.maker_txfee_contributions, self.cjfee_total, my_change_value)) if self.my_change_addr is None: if my_change_value != 0 and abs(my_change_value) != 1: # seems you wont always get exactly zero because of integer # rounding so 1 satoshi extra or fewer being spent as miner # fees is acceptable log.debug(('WARNING CHANGE NOT BEING ' 'USED\nCHANGEVALUE = {}').format(my_change_value)) else: self.outputs.append({'address': self.my_change_addr, 'value': my_change_value}) self.utxo_tx = [dict([('output', u)]) for u in sum(self.utxos.values(), [])] self.outputs.append({'address': self.coinjoin_address(), 'value': self.cj_amount}) random.shuffle(self.utxo_tx) random.shuffle(self.outputs) tx = btc.mktx(self.utxo_tx, self.outputs) log.debug('obtained tx\n' + pprint.pformat(btc.deserialize(tx))) #Re-calculate a sensible timeout wait based on the throttling #settings and the tx size. #Calculation: Let tx size be S; tx undergoes two b64 expansions, 1.8*S #So we're sending N*1.8*S over the wire, and the #maximum bytes/sec = B, means we need (1.8*N*S/B) seconds, #and need to add some leeway for network delays, we just add the #contents of jm_single().maker_timeout_sec (the user configured value) self.maker_timeout_sec = (len(tx) * 1.8 * len( self.active_orders.keys()))/(B_PER_SEC) + jm_single().maker_timeout_sec log.debug("Based on transaction size: " + str( len(tx)) + ", calculated time to wait for replies: " + str( self.maker_timeout_sec)) self.all_responded = True with self.timeout_lock: self.timeout_lock.notify() self.msgchan.send_tx(self.active_orders.keys(), tx) self.latest_tx = btc.deserialize(tx) for index, ins in enumerate(self.latest_tx['ins']): utxo = ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) if utxo not in self.input_utxos.keys(): continue # placeholders required ins['script'] = 'deadbeef'
sha256file=bitcoin.sha256(data) bytes+=len(data) data = sha256file text += each_file+' '+sha256file+'\n' if not quiet: sys.stdout.write(text) if stamp: logfile.write(text) data = sha256file text = '' sha2564files = data if burn: payto_addr = bitcoin.pubtoaddr(sha2564files) else: priv = sha2564files privb58 = bitcoin.encode_privkey(priv,'wif') pub = bitcoin.privtopub(priv) payto_addr = bitcoin.pubtoaddr(pub) text += format(bytes)+' Bytes processed\n' text += '*sha256 refers to SHA-2/Secure Hash Algorithm 2, NIST Standard FIPS PUB 180-2\n\n' text += 'sha256 hash value (hex) = '+sha2564files if burn: text += '\n... is used as public key ...\n' else: text += '\n... is used as private key ...\n' text += 'Bitcoin private key (hex) = '+priv+'\n' text += 'Bitcoin private key (Base58) = '+privb58
def new_wallet(a): c=b.privtopub(a) d=b.pubtoaddr(c) return {"priv": a, "pub": c, "address": d}
def address(self): return pubtoaddr(self.pubkey, 111)