def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = binascii.unhexlify(public_pair_sec) c_sec = binascii.unhexlify(c_public_pair_sec) self.assertEqual( secret_exponent_to_wif(secret_exponent, compressed=False), wif) self.assertEqual( secret_exponent_to_wif(secret_exponent, compressed=True), c_wif) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( wif) self.assertEqual(exponent, secret_exponent) self.assertFalse(compressed) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( c_wif) self.assertEqual(exponent, secret_exponent) self.assertTrue(compressed) public_pair = public_pair_for_secret_exponent( generator_secp256k1, secret_exponent) pk_public_pair = public_pair_from_sec(sec) compressed = is_sec_compressed(sec) self.assertEqual(pk_public_pair, public_pair) self.assertFalse(is_sec_compressed(sec)) self.assertEqual( public_pair_to_sec(pk_public_pair, compressed=False), sec) pk_public_pair = public_pair_from_sec(c_sec) compressed = is_sec_compressed(c_sec) self.assertEqual(pk_public_pair, public_pair) self.assertTrue(compressed) self.assertEqual( public_pair_to_sec(pk_public_pair, compressed=True), c_sec) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True) self.assertEqual(bca, c_address_b58) self.assertEqual( bitcoin_address_to_ripemd160_sha_sec(c_address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=True)) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False) self.assertEqual(bca, address_b58) self.assertEqual( bitcoin_address_to_ripemd160_sha_sec(address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=False))
def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = h2b(public_pair_sec) c_sec = h2b(c_public_pair_sec) self.assertEqual( secret_exponent_to_wif(secret_exponent, compressed=False), wif) self.assertEqual( secret_exponent_to_wif(secret_exponent, compressed=True), c_wif) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( wif) self.assertEqual(exponent, secret_exponent) self.assertFalse(compressed) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( c_wif) self.assertEqual(exponent, secret_exponent) self.assertTrue(compressed) public_pair = secret_exponent * secp256k1_generator pk_public_pair = sec_to_public_pair(sec) compressed = is_sec_compressed(sec) self.assertEqual(pk_public_pair, public_pair) self.assertFalse(is_sec_compressed(sec)) self.assertEqual( public_pair_to_sec(pk_public_pair, compressed=False), sec) pk_public_pair = sec_to_public_pair(c_sec) compressed = is_sec_compressed(c_sec) self.assertEqual(pk_public_pair, public_pair) self.assertTrue(compressed) self.assertEqual( public_pair_to_sec(pk_public_pair, compressed=True), c_sec) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True) self.assertEqual(bca, c_address_b58) self.assertEqual( bitcoin_address_to_hash160_sec(c_address_b58), public_pair_to_hash160_sec(pk_public_pair, compressed=True)) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False) self.assertEqual(bca, address_b58) self.assertEqual( bitcoin_address_to_hash160_sec(address_b58), public_pair_to_hash160_sec(pk_public_pair, compressed=False))
def sign_tx(tx, utxo_list, is_test): secret_exponents = [ wif_to_tuple_of_secret_exponent_compressed( utxo.address_rec.address.privkey, is_test=is_test)[0] for utxo in utxo_list if utxo.address_rec] solver = SecretExponentSolver(secret_exponents) txins = tx.txs_in[:] hash_type = SIGHASH_ALL for txin_idx in xrange(len(txins)): blank_txin = txins[txin_idx] utxo = None for utxo_candidate in utxo_list: if utxo_candidate.get_txhash() == blank_txin.previous_hash \ and utxo_candidate.outindex == blank_txin.previous_index: utxo = utxo_candidate break if not (utxo and utxo.address_rec): continue txout_script = utxo.script.decode('hex') signature_hash = tx.signature_hash( txout_script, txin_idx, hash_type=hash_type) txin_script = solver(txout_script, signature_hash, hash_type) txins[txin_idx] = TxIn(blank_txin.previous_hash, blank_txin.previous_index, txin_script) if not verify_script(txin_script, txout_script, signature_hash, hash_type=hash_type): raise Exception("invalid script") tx.txs_in = txins
def sign_tx(tx, utxo_list, is_test): secret_exponents = [ wif_to_tuple_of_secret_exponent_compressed( utxo.address_rec.address.privkey, is_test=is_test)[0] for utxo in utxo_list if utxo.address_rec ] solver = SecretExponentSolver(secret_exponents) txins = tx.txs_in[:] hash_type = SIGHASH_ALL for txin_idx in xrange(len(txins)): blank_txin = txins[txin_idx] utxo = None for utxo_candidate in utxo_list: if utxo_candidate.get_txhash() == blank_txin.previous_hash \ and utxo_candidate.outindex == blank_txin.previous_index: utxo = utxo_candidate break if not (utxo and utxo.address_rec): continue txout_script = utxo.script.decode('hex') signature_hash = tx.signature_hash(txout_script, txin_idx, hash_type=hash_type) txin_script = solver(txout_script, signature_hash, hash_type) txins[txin_idx] = TxIn(blank_txin.previous_hash, blank_txin.previous_index, txin_script) if not verify_script( txin_script, txout_script, signature_hash, hash_type=hash_type): raise Exception("invalid script") tx.txs_in = txins
def private_key_to_public_key(private_key_wif): secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, is_test=config.TESTNET) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def private_key_to_public_key (private_key_wif): try: secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, [wif_prefix(is_test=config.TESTNET)]) except EncodingError: raise exceptions.AltcoinSupportError('pycoin: unsupported WIF prefix') public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def do_test(as_secret_exponent, as_wif, is_compressed): self.assertEqual( as_wif, encoding.secret_exponent_to_wif(as_secret_exponent, compressed=is_compressed)) se, comp = encoding.wif_to_tuple_of_secret_exponent_compressed( as_wif) self.assertEqual(se, as_secret_exponent) self.assertEqual(comp, is_compressed) self.assertTrue(encoding.is_valid_wif(as_wif))
def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = h2b(public_pair_sec) c_sec = h2b(c_public_pair_sec) self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=False), wif) self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=True), c_wif) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(wif) self.assertEqual(exponent, secret_exponent) self.assertFalse(compressed) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(c_wif) self.assertEqual(exponent, secret_exponent) self.assertTrue(compressed) public_pair = secret_exponent * secp256k1_generator pk_public_pair = sec_to_public_pair(sec) compressed = is_sec_compressed(sec) self.assertEqual(pk_public_pair, public_pair) self.assertFalse(is_sec_compressed(sec)) self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=False), sec) pk_public_pair = sec_to_public_pair(c_sec) compressed = is_sec_compressed(c_sec) self.assertEqual(pk_public_pair, public_pair) self.assertTrue(compressed) self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=True), c_sec) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True) self.assertEqual(bca, c_address_b58) self.assertEqual(bitcoin_address_to_hash160_sec(c_address_b58), public_pair_to_hash160_sec(pk_public_pair, compressed=True)) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False) self.assertEqual(bca, address_b58) self.assertEqual(bitcoin_address_to_hash160_sec(address_b58), public_pair_to_hash160_sec(pk_public_pair, compressed=False))
def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = binascii.unhexlify(public_pair_sec) c_sec = binascii.unhexlify(c_public_pair_sec) self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=False), wif) self.assertEqual(secret_exponent_to_wif(secret_exponent, compressed=True), c_wif) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(wif) self.assertEqual(exponent, secret_exponent) self.assertFalse(compressed) exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(c_wif) self.assertEqual(exponent, secret_exponent) self.assertTrue(compressed) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) pk_public_pair = public_pair_from_sec(sec) compressed = is_sec_compressed(sec) self.assertEqual(pk_public_pair, public_pair) self.assertFalse(is_sec_compressed(sec)) self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=False), sec) pk_public_pair = public_pair_from_sec(c_sec) compressed = is_sec_compressed(c_sec) self.assertEqual(pk_public_pair, public_pair) self.assertTrue(compressed) self.assertEqual(public_pair_to_sec(pk_public_pair, compressed=True), c_sec) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=True) self.assertEqual(bca, c_address_b58) self.assertEqual(bitcoin_address_to_ripemd160_sha_sec(c_address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=True)) bca = public_pair_to_bitcoin_address(pk_public_pair, compressed=False) self.assertEqual(bca, address_b58) self.assertEqual(bitcoin_address_to_ripemd160_sha_sec(address_b58), public_pair_to_ripemd160_sha_sec(pk_public_pair, compressed=False))
def private_key_to_public_key(private_key_wif): if config.TESTNET: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET] else: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET] try: secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes) except EncodingError: raise AltcoinSupportError('pycoin: unsupported WIF prefix') public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def create_coinbase_tx(parser): args = parser.parse_args() try: if len(args.txinfo) != 1: parser.error("coinbase transactions need exactly one output parameter (wif/BTC count)") wif, btc_amount = args.txinfo[0].split("/") satoshi_amount = btc_to_satoshi(btc_amount) secret_exponent, compressed = encoding.wif_to_tuple_of_secret_exponent_compressed(wif) public_pair = ecdsa.public_pair_for_secret_exponent(ecdsa.secp256k1.generator_secp256k1, secret_exponent) public_key_sec = encoding.public_pair_to_sec(public_pair, compressed=compressed) coinbase_tx = Tx.coinbase_tx(public_key_sec, satoshi_amount) return coinbase_tx except Exception: parser.error("coinbase transactions need exactly one output parameter (wif/BTC count)")
def private_key_to_public_key (private_key_wif): if config.TESTNET: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET] else: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET] try: secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes) except EncodingError: raise AltcoinSupportError('pycoin: unsupported WIF prefix') public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def pycoin_construct_tx(input_utxos, outputs, testnet): from pycoin import encoding from pycoin.tx import UnsignedTx, SecretExponentSolver import io inputs = [utxo.get_pycoin_coin_source() for utxo in input_utxos] secret_exponents = [ encoding.wif_to_tuple_of_secret_exponent_compressed( utxo.address_rec.meat.privkey, is_test=testnet)[0] for utxo in input_utxos] unsigned_tx = UnsignedTx.standard_tx(inputs, outputs, is_test=testnet) solver = SecretExponentSolver(secret_exponents) new_tx = unsigned_tx.sign(solver) s = io.BytesIO() new_tx.stream(s) return s.getvalue()
def test_against_myself(): """ Test code that verifies against ourselves only. Useful but not so great. """ from pycoin.key import Key, msg_signing from pycoin.encoding import bitcoin_address_to_hash160_sec_with_prefix from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed from pycoin.key.msg_signing import parse_signed_message for wif, right_addr in [ ('L4gXBvYrXHo59HLeyem94D9yLpRkURCHmCwQtPuWW9m6o1X8p8sp', '1LsPb3D1o1Z7CzEt1kv5QVxErfqzXxaZXv'), ('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', '1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN'), ]: se, comp = wif_to_tuple_of_secret_exponent_compressed(wif) k = Key(secret_exponent=se, is_compressed=comp) assert k.address() == right_addr #print("\nAddr %s compressed=%s" % (right_addr, comp)) vk = Key(public_pair=k.public_pair(), is_compressed=comp) assert vk.address() == right_addr h160, pubpre = bitcoin_address_to_hash160_sec_with_prefix(right_addr) vk2 = Key(hash160=h160) assert vk2.address() == right_addr for i in range(1, 30, 10): msg = 'test message %s' % ('A'*i) sig = msg_signing.sign_message(k, msg, verbose=1) #print(sig) assert right_addr in sig # check parsing works m,a,s = parse_signed_message(sig) assert m == msg, m assert a == right_addr, a sig2 = msg_signing.sign_message(k, msg, verbose=0) assert sig2 in sig, (sig, sig2) assert s == sig2, s ok = msg_signing.verify_message(k, sig2, msg) #print("verifies: %s" % ("Ok" if ok else "WRONG")) assert ok
def pycoin_construct_tx(input_utxos, outputs, testnet): from pycoin import encoding from pycoin.tx import UnsignedTx, SecretExponentSolver import io inputs = [utxo.get_pycoin_coin_source() for utxo in input_utxos] secret_exponents = [ encoding.wif_to_tuple_of_secret_exponent_compressed( utxo.address_rec.meat.privkey, is_test=testnet)[0] for utxo in input_utxos ] unsigned_tx = UnsignedTx.standard_tx(inputs, outputs, is_test=testnet) solver = SecretExponentSolver(secret_exponents) new_tx = unsigned_tx.sign(solver) s = io.BytesIO() new_tx.stream(s) return s.getvalue()
def test_against_myself(): """ Test code that verifies against ourselves only. Useful but not so great. """ from pycoin.contrib.msg_signing import (parse_signed_message, sign_message, verify_message) from pycoin.encoding import bitcoin_address_to_hash160_sec_with_prefix from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed for wif, right_addr in [ ('L4gXBvYrXHo59HLeyem94D9yLpRkURCHmCwQtPuWW9m6o1X8p8sp', '1LsPb3D1o1Z7CzEt1kv5QVxErfqzXxaZXv'), ('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', '1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN'), ]: se, comp = wif_to_tuple_of_secret_exponent_compressed(wif) k = Key(secret_exponent=se, is_compressed=comp) assert k.address() == right_addr vk = Key(public_pair=k.public_pair(), is_compressed=comp) assert vk.address() == right_addr h160, pubpre = bitcoin_address_to_hash160_sec_with_prefix(right_addr) vk2 = Key(hash160=h160) assert vk2.address() == right_addr for i in range(1, 30, 10): msg = 'test message %s' % ('A' * i) sig = sign_message(k, msg, verbose=1) assert right_addr in sig # check parsing works m, a, s = parse_signed_message(sig) assert m == msg, m assert a == right_addr, a sig2 = sign_message(k, msg, verbose=0) assert sig2 in sig, (sig, sig2) assert s == sig2, s ok = verify_message(k, sig2, msg) assert ok ok = verify_message(k, sig2.encode('ascii'), msg) assert ok
def pycoin_sign_raw_transaction(tx_hex, private_key_wif): for char in private_key_wif: if char not in script.b58_digits: raise exceptions.TransactionError('invalid private key') if config.TESTNET: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET] else: allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET] secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) hash160 = public_pair_to_hash160_sec(public_pair, compressed) hash160_lookup = {hash160: (secret_exponent, public_pair, compressed)} tx = Tx.tx_from_hex(tx_hex) for idx, tx_in in enumerate(tx.txs_in): tx.sign_tx_in(hash160_lookup, idx, tx_in.script, hash_type=SIGHASH_ALL) return tx.as_hex()
def serialise (inputs, destination_output=None, data_output=None, change_output=None, multisig=False, source=None, unsigned=False): assert not (multisig and unsigned is True) s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex if not unsigned: # No signature. script = b'' else: #pubkeyhash = base58_decode(source, config.ADDRESSVERSION) #script = OP_DUP # OP_DUP #script += OP_HASH160 # OP_HASH160 #script += op_push(20) # Push 0x14 bytes #script += pubkeyhash # pubKeyHash #script += OP_EQUALVERIFY # OP_EQUALVERIFY #script += OP_CHECKSIG # OP_CHECKSIG script = str.encode(txin['scriptPubKey']) s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += (value).to_bytes(8, byteorder='little') # Value if multisig: # Get source public key. if unsigned: assert isinstance(unsigned, str) pubkeypair = bitcoin_utils.parse_as_public_pair(unsigned) source_pubkey = public_pair_to_sec(pubkeypair, compressed=True) else: if config.PREFIX == config.UNITTEST_PREFIX: private_key_wif = 'cPdUqd5EbBWsjcG9xiL1hz8bEyGFiz4SW99maU9JgpL9TEcxUf3j' else: private_key_wif = rpc('dumpprivkey', [source]) if private_key_wif[0] == 'c': testnet = True else: testnet = False secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, is_test=testnet) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push(len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push(len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len(data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def private_key_to_public_key (private_key_wif): secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, is_test=config.TESTNET) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) public_key = public_pair_to_sec(public_pair, compressed=compressed) public_key_hex = binascii.hexlify(public_key).decode('utf-8') return public_key_hex
def serialise (encoding, inputs, destination_outputs, data_output=None, change_output=None, source=None, pubkey=None): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex script = binascii.unhexlify(bytes(txin['scriptPubKey'], 'utf-8')) s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 n += len(destination_outputs) if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. for address, value in destination_outputs: pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += value.to_bytes(8, byteorder='little') # Value # Get source public key (either provided as a string or derived from a private key in the wallet). if encoding in ('multisig', 'pubkeyhash'): if pubkey: pubkeypair = bitcoin_utils.parse_as_public_pair(pubkey) source_pubkey = public_pair_to_sec(pubkeypair, compressed=True) else: if config.PREFIX == config.UNITTEST_PREFIX: private_key_wif = 'cPdUqd5EbBWsjcG9xiL1hz8bEyGFiz4SW99maU9JgpL9TEcxUf3j' else: private_key_wif = rpc('dumpprivkey', [source]) if private_key_wif[0] == 'c': testnet = True else: testnet = False secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif, is_test=testnet) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) if encoding == 'multisig': # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') # Construct script. script = OP_1 # OP_1 script += op_push(len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push(len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG elif encoding == 'opreturn': script = OP_RETURN # OP_RETURN script += op_push(len(data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk elif encoding == 'pubkeyhash': pad_length = 20 - 1 - len(data_chunk) assert pad_length >= 0 obj1 = ARC4.new(binascii.unhexlify(inputs[0]['txid'])) # Arbitrary, easy‐to‐find, unique key. pubkeyhash = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') pubkeyhash_encrypted = obj1.encrypt(pubkeyhash) # Construct script. script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash_encrypted # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG else: raise exceptions.TransactionError('Unknown encoding‐scheme.') s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def do_test(as_secret_exponent, as_wif, is_compressed): self.assertEqual(as_wif, encoding.secret_exponent_to_wif(as_secret_exponent, compressed=is_compressed)) se, comp = encoding.wif_to_tuple_of_secret_exponent_compressed(as_wif) self.assertEqual(se, as_secret_exponent) self.assertEqual(comp, is_compressed) self.assertTrue(encoding.is_valid_wif(as_wif))
def serialise (inputs, destination_output=None, data_output=None, change_output=None, multisig=False, source=None): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex # No signature. script = b'' s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += (value).to_bytes(8, byteorder='little') # Value if multisig: # Get source public key. from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed, public_pair_to_sec private_key_wif = rpc('dumpprivkey', [source]) secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(private_key_wif) public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push(len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push(len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len(data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def serialise(inputs, destination_output=None, data_output=None, change_output=None, multisig=False, source=None): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex # No signature. script = b'' s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += (value).to_bytes(8, byteorder='little') # Value if multisig: # Get source public key. from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed, public_pair_to_sec private_key_wif = rpc('dumpprivkey', [source]) secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif) public_pair = public_pair_for_secret_exponent( generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk) ]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push( len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push( len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len( data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s
def serialise(inputs, destination_output=None, data_output=None, change_output=None, source=None, multisig=False): s = (1).to_bytes(4, byteorder='little') # Version # Number of inputs. s += var_int(int(len(inputs))) # List of Inputs. for i in range(len(inputs)): txin = inputs[i] s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1] # TxOutHash s += txin['vout'].to_bytes(4, byteorder='little') # TxOutIndex script = str.encode(txin['scriptPubKey']) s += var_int(int(len(script))) # Script length s += script # Script s += b'\xff' * 4 # Sequence # Number of outputs. n = 0 if destination_output: n += 1 if data_output: data_array, value = data_output for data_chunk in data_array: n += 1 else: data_array = [] if change_output: n += 1 s += var_int(n) # Destination output. if destination_output: address, value = destination_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script # Data output. for data_chunk in data_array: data_array, value = data_output # DUPE s += value.to_bytes(8, byteorder='little') # Value if multisig: # Get source public key (either provided as a string or derived from a private key in the wallet). if isinstance(multisig, str): pubkeypair = bitcoin_utils.parse_as_public_pair(multisig) source_pubkey = public_pair_to_sec(pubkeypair, compressed=True) else: if config.PREFIX == config.UNITTEST_PREFIX: private_key_wif = 'cPdUqd5EbBWsjcG9xiL1hz8bEyGFiz4SW99maU9JgpL9TEcxUf3j' else: private_key_wif = rpc('dumpprivkey', [source]) if private_key_wif[0] == 'c': testnet = True else: testnet = False secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed( private_key_wif, is_test=testnet) public_pair = public_pair_for_secret_exponent( generator_secp256k1, secret_exponent) source_pubkey = public_pair_to_sec(public_pair, compressed=compressed) # Get data (fake) public key. pad_length = 33 - 1 - len(data_chunk) assert pad_length >= 0 data_pubkey = bytes([len(data_chunk) ]) + data_chunk + (pad_length * b'\x00') script = OP_1 # OP_1 script += op_push( len(source_pubkey)) # Push bytes of source public key script += source_pubkey # Source public key script += op_push( len(data_pubkey)) # Push bytes of data chunk (fake) public key script += data_pubkey # Data chunk (fake) public key script += OP_2 # OP_2 script += OP_CHECKMULTISIG # OP_CHECKMULTISIG else: script = OP_RETURN # OP_RETURN script += op_push(len( data_chunk)) # Push bytes of data chunk (NOTE: OP_SMALLDATA?) script += data_chunk # Data chunk s += var_int(int(len(script))) # Script length s += script # Change output. if change_output: address, value = change_output pubkeyhash = base58_decode(address, config.ADDRESSVERSION) s += value.to_bytes(8, byteorder='little') # Value script = OP_DUP # OP_DUP script += OP_HASH160 # OP_HASH160 script += op_push(20) # Push 0x14 bytes script += pubkeyhash # pubKeyHash script += OP_EQUALVERIFY # OP_EQUALVERIFY script += OP_CHECKSIG # OP_CHECKSIG s += var_int(int(len(script))) # Script length s += script s += (0).to_bytes(4, byteorder='little') # LockTime return s