def sign_tx(self, pw): if not self.is_wallet_loaded: raise Exception('Tried to spend when wallet not loaded.') if not self.is_dest_addr_set: raise Exception('Tried to spend when destination address not set.') if not self.is_send_amount_set: raise Exception('Tried to spend when amount not set.') if self.send_amount + self.txfee > self.balance: raise LowBalanceError("Insufficient funds to send {0} + {1} BTC.".format(core.satoshi_to_btc(self.send_amount), core.satoshi_to_btc(self.txfee))) try: prv = wallet.decrypt_privkey(self.encr_privkey, pw) addr = bc.privtoaddr(prv, self.magic_byte) except: raise PasswordError("Wrong password!") if addr != self.addr: raise Exception('Address from wallet does not match address from private key!') tx_ins, tx_outs = core.simple_tx_inputs_outputs(self.addr, self.unspent, self.dest_addr, self.send_amount, self.txfee) # Make transaction tx = bc.mktx(tx_ins, tx_outs) # Sign transaction for i in range(len(tx_ins)): tx = bc.sign(tx,i,prv) return tx_ins, tx_outs, tx, bc.deserialize(tx)
def sign_tx(unsigned_raw_tx, privatekey): tx = unsigned_raw_tx detx = pybitcointools.deserialize(tx) input_length = len(detx['ins']) for i in range(0, input_length): tx = pybitcointools.sign(tx, i, privatekey) return tx
def process_tx(addr_queue, blockheight, tx): tx_obj = pybitcointools.deserialize(tx.encode('hex')) for vout in tx_obj['outs']: addr_temp = pybitcointools.script_to_address(vout['script']) if addr_temp and addr_temp[0] in ['1','3']: addr_queue.put((blockheight, addr_temp))
def add_op_return(unsigned_raw_tx, message): deserialized_tx = pybitcointools.deserialize(unsigned_raw_tx) newscript = make_op_return_script(message) newoutput = {} newoutput['value'] = 0 newoutput['script'] = newscript deserialized_tx['outs'].append(newoutput) reserialized_tx = pybitcointools.serialize(deserialized_tx) return reserialized_tx
def verify_vin_old(txid, index): # get raw transaction (txid) <-- vin[0]: scriptSig rpc = BtcRpc("http://*****:*****@127.0.0.1:8332") rawtx = rpc.rpc.getrawtransaction(txid) jsontxverbose = rpc.rpc.getrawtransaction(txid, 1) #pprint.pprint(jsontxverbose) jsontx = pybitcointools.deserialize(rawtx) pprint.pprint(jsontx) scriptSigasm = jsontxverbose['vin'][index]['scriptSig']['asm'] logger.debug(scriptSigasm) scriptSig = jsontx['ins'][index]['script'] sigpubdecoded = asn1der.decode( scriptSig.decode("hex")[1:]) # skip first push sig = long(sigpubdecoded[0][0]), long(sigpubdecoded[0][1]) pubkey = sigpubdecoded[1] sighash_type = pubkey[0] logger.debug("sighash type: %r" % sighash_type) push = pubkey[1] btc_pubkey_type = pubkey[2] pubkey = pubkey[3:] logger.debug("r %s s %s" % (hex(sig[0]), hex(sig[1]))) logger.debug(pubkey.encode("hex")) # generate signdata # replace input script with funding script of 17SkEw2md5avVNyYgj6RiXuQKNwkXaxFyQ for txin in jsontx['ins']: txin['script'] = '' funding_txid = jsontxverbose['vin'][index]['txid'] funding_tx = rpc.rpc.getrawtransaction(funding_txid, 1) #pprint.pprint(funding_tx) funding_script = funding_tx['vout'][0]['scriptPubKey']['hex'] jsontx['ins'][index]['script'] = funding_script signdata = pybitcointools.serialize(jsontx) + "01000000" #SIGHASH ALL import hashlib digest = hashlib.sha256(hashlib.sha256( signdata.decode("hex")).digest()).digest() logger.debug(digest[::-1].encode("hex")) vk = VerifyingKey.from_string(pubkey, curve=curve) logger.debug("verify --> %s " % (vk.pubkey.verifies( int(digest.encode("hex"), 16), Signature(sig[0], sig[1])))) #print vk.verify_digest(scriptSigasm.split("[ALL]",1)[0].decode("hex"), digest, sigdecode=ecdsa.util.sigdecode_der) return BTCSignature( sig=Signature(sig[0], sig[1]), h=int(digest.encode("hex"), 16), pubkey=pubkey, )
def dump_tx_ecdsa(txid, i): tx = getrawtx(txid) vin = tx['vin'][i] if 'coinbase' in vin: return prev_tx = getrawtx(vin['txid']) prev_vout = prev_tx['vout'][vin['vout']] prev_type = prev_vout['scriptPubKey']['type'] script = prev_vout['scriptPubKey']['hex'] if prev_type == 'pubkeyhash': sig, pub = vin['scriptSig']['asm'].split(' ') elif prev_type == 'pubkey': sig = vin['scriptSig']['asm'] pub, _ = prev_vout['scriptPubKey']['asm'].split(' ') else: logger.warning("%6d %s %4d ERROR_UNHANDLED_SCRIPT_TYPE" % (txid, i)) raise x = pub[2:66] #print sig if sig[-1] == ']': sig, hashcode_txt = sig.strip(']').split('[') if hashcode_txt == 'ALL': hashcode = 1 elif hashcode_txt == 'SINGLE': hashcode = 3 else: print hashcode_txt logger.warning("xx %s %4d ERROR_UNHANDLED_HASHCODE" % (txid, hashcode_txt)) raise else: hashcode = int(sig[-2:], 16) sig = sig[:-2] modtx = pybitcointools.serialize( pybitcointools.signature_form(pybitcointools.deserialize(tx['hex']), i, script, hashcode)) z = hexlify(pybitcointools.txhash(modtx, hashcode)) _, r, s = pybitcointools.der_decode_sig(sig) r = pybitcointools.encode(r, 16, 64) s = pybitcointools.encode(s, 16, 64) #print verify_tx_input(tx['hex'], i, script, sig, pub) return {'txid': txid, 'i': i, 'x': x, 'r': r, 's': s, 'z': z, 'pub': pub}
def verify_vin(txid, index): txdump = dump_tx_ecdsa(txid, index) #i, pub, txid, s, r, x, z # | | \--- hash # | \------ pub decoded? # \---------------------- pub orig? import pprint pprint.pprint(txdump) print txdump['z'].decode("hex") print int(txdump['z'],16) def fix_pubkey(p): if p.startswith("04"): return p[2:] return p txdump['pub'] = fix_pubkey(txdump['pub']) #vk = VerifyingKey.from_public_point(int(txdump['x'],16),curve=curve) #vk = VerifyingKey.from_string(txdump['pub'], curve=curve) #print vk #logger.debug("verify --> %s " % (vk.pubkey.verifies(int(digest.encode("hex"), 16), Signature(sig[0], sig[1])))) # get raw transaction (txid) <-- vin[0]: scriptSig rpc = BtcRpc("http://*****:*****@127.0.0.1:8332") rawtx = rpc.rpc.getrawtransaction(txid) jsontxverbose = rpc.rpc.getrawtransaction(txid,1) #pprint.pprint(jsontxverbose) jsontx = pybitcointools.deserialize(rawtx) pprint.pprint(jsontx) scriptSigasm = jsontxverbose['vin'][index]['scriptSig']['asm'] logger.debug(scriptSigasm) scriptSig = jsontx['ins'][index]['script'] sigpubdecoded = asn1der.decode(scriptSig.decode("hex")[1:]) # skip first push sig = long(sigpubdecoded[0][0]), long(sigpubdecoded[0][1]) pubkey = sigpubdecoded[1] sighash_type = pubkey[0] logger.debug("sighash type: %r" % sighash_type) push = pubkey[1] btc_pubkey_type = pubkey[2] pubkey = pubkey[3:] logger.debug("r %s s %s"%(hex(sig[0]),hex(sig[1]))) logger.debug("pubkey: %r"%pubkey.encode("hex")) logger.debug("txdump: %r"%txdump['pub']) ''' # generate signdata # replace input script with funding script of 17SkEw2md5avVNyYgj6RiXuQKNwkXaxFyQ for txin in jsontx['ins']: txin['script']='' funding_txid = jsontxverbose['vin'][index]['txid'] funding_tx = rpc.rpc.getrawtransaction(funding_txid,1) #pprint.pprint(funding_tx) funding_script = funding_tx['vout'][0]['scriptPubKey']['hex'] jsontx['ins'][index]['script']=funding_script signdata= pybitcointools.serialize(jsontx) + "01000000" #SIGHASH ALL import hashlib digest = hashlib.sha256(hashlib.sha256(signdata.decode("hex")).digest()).digest() logger.debug(digest[::-1].encode("hex")) pause("--->") ''' pause("create verifying key...") vk = VerifyingKey.from_string(txdump['pub'].decode("hex"), curve=curve) digest = txdump['z'] print repr(pubkey) print repr(txdump['pub']) z = int(digest.decode("hex"),16) verifies = vk.pubkey.verifies(z,Signature(sig[0],sig[1])) logger.debug("verify --> %s "%(verifies)) if not verifies: pause("--verify false!--",critical=True) #print vk.verify_digest(scriptSigasm.split("[ALL]",1)[0].decode("hex"), digest, sigdecode=ecdsa.util.sigdecode_der) return BTCSignature(sig=Signature(sig[0],sig[1]), h=z, pubkey=pubkey, )
""" step 4: raw transaction info """ import os,sys,inspect currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) #parentdir = os.path.dirname(currentdir) #print parentdir #sys.path.insert(0,parentdir) #parentpath = os.path.join(sys.path[0], '..') #print parentpath #sys.path.insert(1, parentpath) #sys.path.insert(0,'../..') import pybitcointools import pprint tx = '0100000002a0ae9d839ed51c9d6d299b2b3c508b935858371b283bcb1e953bc776f61c6c75000000008c493046022100b999de2e23127ec2edf16e2f267b4c2df57b9766059369cee85cbc0a41be6882022100d09c405f825eec986ca2bf6f35d1267ad7d595042fca4b4f7af3f9adfea68d330141040bf69616981e5970c992a0762f441abcadfed9fc4630fa5e1b82ab00e81d16905d3820e073e1bd4a9dcfed336f4bf25edc634c2e174989767d299748359c2dafffffffff52be06c2c43c4d0ec3c208b8b8ddbcb32ac4fdb3481addfb90498267df3ba07b010000008b48304502201193da6f0c1b3f15497415fd75743439374939191331bd7ca1ac183580ad4273022100e435bd3c48929d9789810634af47a0461e684dd490132a9c5757af86296ce0d70141046cc9eeffe66726abb725d191537f87c023202eb13ede9031d7adb80ecb0ddc9aa380cb2659747b850ea577cf04f01248ca9291976523a94ef0a907e6bb15bd55ffffffff02e0c03b00000000001976a914e1e1ffc33423807d6914de976738bbdc01477c2d88ac8c2e0100000000001976a91419e75cce5ff697a01e14ec3ebcc9a4523e44caf188ac00000000' tx_structure = pybitcointools.deserialize(tx) pprint.pprint(tx_structure)
break except ValueError: print "Decode error (carriage returns are not allowed)" continue availableBalance = base.check_unspent(data["u"]) # build tx outs = [{'value' : availableBalance - sum(data["amounts"]), 'address' : data["source"]}] # change if outs[0]["value"] == 0: outs = [] for i, t in enumerate(data["targets"]): outs.append({'value' : data["amounts"][i], 'address' : data["targets"][i]}) rtx = pbt.mktx(data["u"], outs) # serialized tx dtx = pbt.deserialize(rtx) base.display_dtx(dtx, data) print "Check balance and targets. Remove your data source (USB-stick)." print "Press <enter> to proceed, <ctrl-c> to cancel." raw_input() print print "Enter private key or (double) Electrum seed:" priv = raw_input().strip() if " " in priv: seed = mnemonic.mn_decode(priv.split(" ")) priv = pbt.electrum_privkey(seed, 0, 0) # root key source = pbt.privkey_to_address(priv) if source != data["source"]:
root.update() sigRtx = root.clipboard_get() if sigRtx == cb: time.sleep(0.5) continue cb = sigRtx print cb except tk.TclError: time.sleep(0.5) continue sigRtx = pbt.changebase(sigRtx.strip(), 58, 16) if len(sigRtx) % 2: sigRtx = "0" + sigRtx sigDtx = {} try: sigDtx = pbt.deserialize(sigRtx) except: pass if sigDtx["ins"][0]["script"]: break except (IndexError, KeyError): pass else: raise time.sleep(0.5) base.display_dtx(sigDtx, data) sigRtx = pbt.serialize(sigDtx) print "About to publish tx" print "Press <enter> to proceed, <ctrl-c> to cancel."
def convert(txhex): return deserialize(txhex)
""" step 4: raw transaction info """ import os, sys, inspect currentdir = os.path.dirname( os.path.abspath(inspect.getfile(inspect.currentframe()))) #parentdir = os.path.dirname(currentdir) #print parentdir #sys.path.insert(0,parentdir) #parentpath = os.path.join(sys.path[0], '..') #print parentpath #sys.path.insert(1, parentpath) #sys.path.insert(0,'../..') import pybitcointools import pprint tx = '0100000002a0ae9d839ed51c9d6d299b2b3c508b935858371b283bcb1e953bc776f61c6c75000000008c493046022100b999de2e23127ec2edf16e2f267b4c2df57b9766059369cee85cbc0a41be6882022100d09c405f825eec986ca2bf6f35d1267ad7d595042fca4b4f7af3f9adfea68d330141040bf69616981e5970c992a0762f441abcadfed9fc4630fa5e1b82ab00e81d16905d3820e073e1bd4a9dcfed336f4bf25edc634c2e174989767d299748359c2dafffffffff52be06c2c43c4d0ec3c208b8b8ddbcb32ac4fdb3481addfb90498267df3ba07b010000008b48304502201193da6f0c1b3f15497415fd75743439374939191331bd7ca1ac183580ad4273022100e435bd3c48929d9789810634af47a0461e684dd490132a9c5757af86296ce0d70141046cc9eeffe66726abb725d191537f87c023202eb13ede9031d7adb80ecb0ddc9aa380cb2659747b850ea577cf04f01248ca9291976523a94ef0a907e6bb15bd55ffffffff02e0c03b00000000001976a914e1e1ffc33423807d6914de976738bbdc01477c2d88ac8c2e0100000000001976a91419e75cce5ff697a01e14ec3ebcc9a4523e44caf188ac00000000' tx_structure = pybitcointools.deserialize(tx) pprint.pprint(tx_structure)