def dummy_op_return_tx(key, message, spendables, fee=10000): address = key.address() if len(message) > 80: raise ValueError("message must not be longer than 80 bytes") message = hexlify(message).decode() bitcoin_sum = sum(spendable.coin_value for spendable in spendables) if bitcoin_sum < fee: raise Exception("not enough bitcoin to cover fee") inputs = [spendable.tx_in() for spendable in spendables] outputs = [] if bitcoin_sum > fee: change_output_script = standard_tx_out_script(address) outputs.append(TxOut(bitcoin_sum - fee, change_output_script)) op_return_output_script = script.tools.compile('OP_RETURN %s' % message) outputs.append(TxOut(0, op_return_output_script)) tx = Tx(version=1, txs_in=inputs, txs_out=outputs) tx.set_unspents(spendables) sign_tx(tx, wifs=[key.wif()]) return tx
def write_opreturn(bitcoin_address, bitcoin_private_key, raw_message, fee=5000, push=False): message = hexlify(raw_message.encode()).decode('utf8') spendables = spendables_for_address(bitcoin_address) spendables = [s for s in spendables] bitcoin_sum = sum([spendable.coin_value for spendable in spendables]) inputs = [spendable.tx_in() for spendable in spendables] outputs = [] if (bitcoin_sum > fee): change_output_script = standard_tx_out_script(bitcoin_address) print change_output_script outputs.append(TxOut(bitcoin_sum - fee, change_output_script)) ## Build the OP_RETURN output with our message op_return_output_script = script.tools.compile("OP_RETURN %s" % message) outputs.append(TxOut(0, op_return_output_script)) ## Create the transaction and sign it with the private key tx = Tx(version=1, txs_in=inputs, txs_out=outputs) tx.set_unspents(spendables) sign_tx(tx, wifs=[bitcoin_private_key]) print tx.as_hex() if not push: return tx.as_hex() else: pushtx(tx.as_hex()) else: print "INADEQUATE FUNDS"
def write_transfer(sender, sender_priv, recipient, message, fee=m.default_fee, avoid_inputs=[]): message = hexlify(message.encode()).decode('utf8') spendables = spendables_for_address(sender) spendables = [s for s in spendables if not spendable_to_legible(s.tx_in()) in avoid_inputs] bitcoin_sum = sum([spendable.coin_value for spendable in spendables]) inputs = [spendable.tx_in() for spendable in spendables] outputs = [] if bitcoin_sum > fee + m.dust*2: remaining = bitcoin_sum - fee - m.dust*2 dest_output_script = standard_tx_out_script(recipient) change_output_script = standard_tx_out_script(sender) btc_change_output_script = standard_tx_out_script(sender) op_return_output_script = script.tools.compile("OP_RETURN %s" % message) outputs.append(TxOut(m.dust, dest_output_script)) outputs.append(TxOut(m.dust, change_output_script)) outputs.append(TxOut(remaining, btc_change_output_script)) outputs.append(TxOut(0, op_return_output_script)) tx = Tx(version=1, txs_in=inputs, txs_out=outputs) tx.set_unspents(spendables) sign_tx(tx, wifs=[sender_priv]) print tx.as_hex() return tx.as_hex() else: print "INADEQUATE FUNDS"
def create_raw_transaction(self, escrow, fees): logging.info('starting raw transaction to payout address %s' % escrow['sellerpayoutaddress']) # convenience method provided by pycoin to get spendables from insight server insight = InsightService(INSIGHT) spendables = insight.spendables_for_address(escrow['multisigaddress']) # create the tx_in txs_in = [] for s in spendables: txs_in.append(s.tx_in()) script = standard_tx_out_script(escrow['multisigaddress']) tx_out = TxOut(fees['seller'], script) txs_out = [tx_out] tx1 = Tx(version=1, txs_in=txs_in, txs_out=txs_out) tx1.set_unspents(txs_out) # this will be the hex of the tx we're going to send in the POST request hex_tx = tx1.as_hex(include_unspents=True) return hex_tx
def op_return_this(privatekey, text, prefix = "KEYSTAMP:", bitcoin_fee = 10000): bitcoin_keyobj = get_key(privatekey) bitcoin_address = bitcoin_keyobj.bitcoin_address() ## Get the spendable outputs we are going to use to pay the fee all_spendables = get_spendables_blockcypher(bitcoin_address) spendables = [] value = 0 for unspent in all_spendables: while value < bitcoin_fee + 10000: coin_value = unspent.get("value") script = h2b(unspent.get("script_hex")) previous_hash = h2b_rev(unspent.get("tx_hash")) previous_index = unspent.get("index") spendables.append(Spendable(coin_value, script, previous_hash, previous_index)) value += coin_value bitcoin_sum = sum(spendable.coin_value for spendable in spendables) if(bitcoin_sum < bitcoin_fee): print "ERROR: not enough balance: available: %s - fee: %s" %(bitcoin_sum, bitcoin_fee) return False ## Create the inputs we are going to use inputs = [spendable.tx_in() for spendable in spendables] ## If we will have change left over create an output to send it back outputs = [] if (bitcoin_sum > bitcoin_fee): change_output_script = standard_tx_out_script(bitcoin_address) total_amout = bitcoin_sum - bitcoin_fee outputs.append(TxOut(total_amout, change_output_script)) # home_address = standard_tx_out_script(bitcoin_address) # #TODO: it needs some love and IQ on input mananagement stuff # outputs.append(TxOut((bitcoin_sum - bitcoin_fee), home_address)) ## Build the OP_RETURN output with our message if prefix is not None and (len(text) + len(prefix) <= 80): text = prefix + text message = hexlify(text.encode()).decode('utf8') op_return_output_script = tools.compile("OP_RETURN %s" % message) outputs.append(TxOut(0, op_return_output_script)) ## Create the transaction and sign it with the private key tx = Tx(version=1, txs_in=inputs, txs_out=outputs) # print tx.as_hex() # print spendables tx.set_unspents(spendables) sign_tx(tx, wifs=[privatekey]) print "singed_tx: %s" %tx.as_hex() #TODO: uncomment this when its ready to push data to blockchian tx_hash = broadcast_tx_blockr(tx.as_hex()) return tx_hash
def standard_tx(coins_from, coins_to): txs_in = [] unspents = [] for h, idx, tx_out in coins_from: txs_in.append(TxIn(h, idx)) unspents.append(tx_out) txs_out = [] for coin_value, bitcoin_address in coins_to: txs_out.append(TxOut(coin_value, standard_tx_out_script(bitcoin_address))) version, lock_time = 1, 0 tx = Tx(version, txs_in, txs_out, lock_time) tx.set_unspents(unspents) return tx
def standard_tx(coins_from, coins_to): txs_in = [] unspents = [] for h, idx, tx_out in coins_from: txs_in.append(TxIn(h, idx)) unspents.append(tx_out) txs_out = [] for coin_value, bitcoin_address in coins_to: txs_out.append( TxOut(coin_value, standard_tx_out_script(bitcoin_address))) version, lock_time = 1, 0 tx = Tx(version, txs_in, txs_out, lock_time) tx.set_unspents(unspents) return tx
def send_op_return_tx(key, message, fee=10000): """ Send an transaction with an OP_RETURN output. Args: key: the Bitcoin Key to send the transaction from. message: the message to include in OP_RETURN. fee: the miner fee that should be paid in Satoshis. Returns: The broadcasted Tx. """ address = key.address() if len(message) > 80: raise ValueError("message must not be longer than 80 bytes") message = hexlify(message).decode() spendables = spendables_for_address(address) bitcoin_sum = sum(spendable.coin_value for spendable in spendables) if bitcoin_sum < fee: raise Exception("not enough bitcoin to cover fee") inputs = [spendable.tx_in() for spendable in spendables] outputs = [] if bitcoin_sum > fee: change_output_script = standard_tx_out_script(address) outputs.append(TxOut(bitcoin_sum - fee, change_output_script)) op_return_output_script = script.tools.compile('OP_RETURN %s' % message) outputs.append(TxOut(0, op_return_output_script)) tx = Tx(version=1, txs_in=inputs, txs_out=outputs) tx.set_unspents(spendables) sign_tx(tx, wifs=[key.wif()]) broadcast_tx(tx) return tx
def _test_sighash_single(self, netcode): k0 = Key(secret_exponent=PRIV_KEYS[0], is_compressed=True, netcode=netcode) k1 = Key(secret_exponent=PRIV_KEYS[1], is_compressed=True, netcode=netcode) k2 = Key(secret_exponent=PRIV_KEYS[2], is_compressed=True, netcode=netcode) k3 = Key(secret_exponent=PRIV_KEYS[3], is_compressed=True, netcode=netcode) k4 = Key(secret_exponent=PRIV_KEYS[4], is_compressed=True, netcode=netcode) k5 = Key(secret_exponent=PRIV_KEYS[5], is_compressed=True, netcode=netcode) # Fake a coinbase transaction coinbase_tx = Tx.coinbase_tx(k0.sec(), 500000000) coinbase_tx.txs_out.append( TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k1.sec())))) coinbase_tx.txs_out.append( TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k2.sec())))) self.assertEqual( '2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a', b2h_rev(coinbase_tx.hash())) # Make the test transaction txs_in = [ TxIn(coinbase_tx.hash(), 0), TxIn(coinbase_tx.hash(), 1), TxIn(coinbase_tx.hash(), 2), ] txs_out = [ TxOut(900000000, standard_tx_out_script(k3.address())), TxOut(800000000, standard_tx_out_script(k4.address())), TxOut(800000000, standard_tx_out_script(k5.address())), ] tx = Tx(1, txs_in, txs_out) tx.set_unspents(coinbase_tx.txs_out) self.assertEqual( '791b98ef0a3ac87584fe273bc65abd89821569fd7c83538ac0625a8ca85ba587', b2h_rev(tx.hash())) sig_type = SIGHASH_SINGLE sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual( 'cc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual( '93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual( '53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2)) sig_type = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual( '2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual( 'e3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual( 'bacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2))
def _test_sighash_single(self, netcode): k0 = Key(secret_exponent=PRIV_KEYS[0], is_compressed=True, netcode=netcode) k1 = Key(secret_exponent=PRIV_KEYS[1], is_compressed=True, netcode=netcode) k2 = Key(secret_exponent=PRIV_KEYS[2], is_compressed=True, netcode=netcode) k3 = Key(secret_exponent=PRIV_KEYS[3], is_compressed=True, netcode=netcode) k4 = Key(secret_exponent=PRIV_KEYS[4], is_compressed=True, netcode=netcode) k5 = Key(secret_exponent=PRIV_KEYS[5], is_compressed=True, netcode=netcode) # Fake a coinbase transaction coinbase_tx = Tx.coinbase_tx(k0.sec(), 500000000) coinbase_tx.txs_out.append(TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k1.sec())))) coinbase_tx.txs_out.append(TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k2.sec())))) self.assertEqual('2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a', b2h_rev(coinbase_tx.hash())) # Make the test transaction txs_in = [ TxIn(coinbase_tx.hash(), 0), TxIn(coinbase_tx.hash(), 1), TxIn(coinbase_tx.hash(), 2), ] txs_out = [ TxOut(900000000, standard_tx_out_script(k3.address())), TxOut(800000000, standard_tx_out_script(k4.address())), TxOut(800000000, standard_tx_out_script(k5.address())), ] tx = Tx(1, txs_in, txs_out) tx.set_unspents(coinbase_tx.txs_out) self.assertEqual('791b98ef0a3ac87584fe273bc65abd89821569fd7c83538ac0625a8ca85ba587', b2h_rev(tx.hash())) sig_type = SIGHASH_SINGLE sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual('cc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual('93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual('53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2)) sig_type = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual('2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual('e3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual('bacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2))
exit("Message must be 80 characters or less") message = hexlify(raw_message.encode()).decode('utf8') ## Get the spendable outputs we are going to use to pay the fee spendables = spendables_for_address(bitcoin_address) bitcoin_sum = sum(spendable.coin_value for spendable in spendables) if(bitcoin_sum < bitcoin_fee): exit("Not enough satoshis to cover the fee. found: {sum} need: {fee}" .format(sum=bitcoin_sum,fee=bitcoin_fee)) ## Create the inputs we are going to use inputs = [spendable.tx_in() for spendable in spendables] ## If we will have change left over create an output to send it back outputs = [] if (bitcoin_sum > bitcoin_fee): change_output_script = standard_tx_out_script(bitcoin_address) outputs.append(TxOut(bitcoin_sum - bitcoin_fee, change_output_script)) ## Build the OP_RETURN output with our message op_return_output_script = script.tools.compile("OP_RETURN %s" % message) outputs.append(TxOut(0, op_return_output_script)) ## Create the transaction and sign it with the private key tx = Tx(version=1, txs_in=inputs, txs_out=outputs) tx.set_unspents(spendables) signed_tx = sign_tx(tx, wifs=[bitcoin_private_key]) ## Send the signed transaction to the network through bitcoind ## Note: that os.system() prints the response for us system("bitcoin-cli sendrawtransaction %s" % tx.as_hex())
address = address_for_pay_to_script(underlying_script) ## going to create a spend from this address. This should be the code on the web server spendables = insight.spendables_for_address(address) txs_in = [] for s in spendables: print s txs_in.append(s.tx_in()) # make tx_out on web server script = standard_tx_out_script(address) tx_out = TxOut(100000, script) txs_out = [tx_out] tx1 = Tx(version=1, txs_in=txs_in, txs_out=txs_out) tx1.set_unspents(txs_out) txhex = tx1.as_hex(include_unspents=True) # send txhex to private key server tx2 = Tx.tx_from_hex(txhex) script = standard_tx_out_script("1F8P3QEErMhm3fw6o23brRNQVaSMrG1maE") tx_out = TxOut(50000, script) script = standard_tx_out_script("1Dv9YWfVYMK1FjBhrCBc1diajSZKBj78MB") tx2_out = TxOut(50000, script) txs_out = [tx_out, tx2_out] tx2.txs_out = txs_out hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:M])