def _create_addresses(tx,batch,testnet=True): """ testnet is TRUE always. Change this for mainnet later. """ batch_size = 5 app_log.info(f" batch size {batch_size}. Represents the amount of blocks whose outputs are being encoded to addresses.") for height in range(batch*batch_size, batch_size*(batch + 1)): result = tx.run("MATCH (b:block {height:$height}) " "MATCH (x)<-[:CREATES]-(t:transaction)<-[:CONTAINS]-(b) " "RETURN x.script_pubkey, x.index, t.id", height=height) addresses = [] for output in result.data(): address = None addr_type = None raw_script_pubkey = output["x.script_pubkey"] b_sp = bytes.fromhex(raw_script_pubkey) length = encode_varint(len(b_sp)) stream = BytesIO(length+b_sp) try: script_pubkey = Script.parse(stream) if script_pubkey.is_p2pkh_script_pubkey(): address= h160_to_p2pkh_address(script_pubkey.cmds[2], testnet) addr_type = "P2PKH" elif script_pubkey.is_p2sh_script_pubkey(): address= h160_to_p2sh_address(script_pubkey.cmds[1], testnet) addr_type = "P2SH" elif script_pubkey.is_p2wpkh_script_pubkey() or script_pubkey.is_p2wsh_script_pubkey(): if testnet: address = segwit_addr.encode("tb",0,script_pubkey.cmds[1]) else: address = segwit_addr.encode("bc",0,script_pubkey.cmds[1]) if script_pubkey.is_p2wpkh_script_pubkey(): addr_type = "P2WPKH" else: addr_type = "P2WSH" elif len(script_pubkey.cmds)==2 and script_pubkey.cmds[1]==0xac: try: address = script_pubkey.cmds[0].hex() addr_type = "P2PK" except: app_log.info(f"P2PK failed {script_pubkey.cmds[0]} from tx: {output['t.id']}") except: app_log.info(f"script parsing failed in tx {output['t.id']} index {output['x.index']} ") if address is not None: address_dict = { "address":address, "type": addr_type, "tx_id":output["t.id"], "index":output["x.index"] } addresses.append(address_dict) if len(addresses)>0: result = tx.run("FOREACH (address in $addresses | \n" "MERGE (o:output {index:address.index})<-[:CREATES]-(:transaction {id:address.tx_id}) \n" "MERGE (a:address {address:address.address}) SET a.type=address.type \n" "MERGE (a)-[:HAS]->(o) )", addresses=addresses) return
def hwif_to_bech32_address(hwif): testnet, depth, parent_fingerprint, child_index, chain_code, secret_key, public_key = from_hwif( hwif) data = ser_p(public_key) keyhash = hash160(data) hrp = "tb" if testnet else "bc" return segwit_addr.encode(hrp, 0, keyhash)
def encode_address(_script_pubkey, testnet=True): address = "" addr_type = "" length = encode_varint(len(_script_pubkey)) stream = BytesIO(length + _script_pubkey) #stream = BytesIO(_script_pubkey) try: script_pubkey = Script.parse(stream) if script_pubkey.is_p2pkh_script_pubkey(): address = h160_to_p2pkh_address(script_pubkey.cmds[2], testnet) addr_type = "P2PKH" elif script_pubkey.is_p2sh_script_pubkey(): address = h160_to_p2sh_address(script_pubkey.cmds[1], testnet) addr_type = "P2SH" elif script_pubkey.is_p2wpkh_script_pubkey( ) or script_pubkey.is_p2wsh_script_pubkey(): if testnet: address = segwit_addr.encode("tb", 0, script_pubkey.cmds[1]) else: address = segwit_addr.encode("bc", 0, script_pubkey.cmds[1]) if script_pubkey.is_p2wpkh_script_pubkey(): addr_type = "P2WPKH" else: addr_type = "P2WSH" elif len(script_pubkey.cmds ) == 2 and script_pubkey.cmds[1] == 0xac: try: address = script_pubkey.cmds[0].hex() addr_type = "P2PK" except: app_log.info( f"P2PK failed {script_pubkey.cmds[0]} from tx: {output['t.id']}" ) except: app_log.info(f"script parsing failed.") return address, addr_type
def test_valid_address(self): """Test whether valid addresses decode to the correct output.""" for (address, hexscript) in VALID_ADDRESS: hrp = "bc" witver, witprog = segwit_addr.decode(hrp, address) if witver is None: hrp = "tb" witver, witprog = segwit_addr.decode(hrp, address) self.assertIsNotNone(witver) scriptpubkey = segwit_scriptpubkey(witver, witprog) self.assertEqual(scriptpubkey, binascii.unhexlify(hexscript)) addr = segwit_addr.encode(hrp, witver, witprog) self.assertEqual(address.lower(), addr)
def wif_to_bech32(wif): data = b58decode_check(wif) prefix, data = data[0:1], data[1:] testnet = prefix == b"\xef" if not testnet: assert prefix == b"\x80" compressed = len(data) == 33 if compressed: suffix, data = data[-1], data[:-1] assert suffix == 1 secret_exponent = parse_256(data) public_pair = (ecdsa.generator_secp256k1 * secret_exponent).pair() data = ser_p(public_pair) keyhash = hash160(data) hrp = "tb" if testnet else "bc" return segwit_addr.encode(hrp, 0, keyhash)
def elm_nosig(command_set, text, dest_addr, coeff=10, len_offset=100, final_amount=1000): payto = command_set['payto'] broadcast = command_set['broadcast'] pref = dest_addr[:2] script = putPushdata(b"", text.encode()) + b"\x75\x51" init_amount = coeff * (len(script) + len_offset) + final_amount dest_script = segwit_addr.encode(pref, 0, el.sha256(script)) tx1 = payto(dest_script, init_amount * 0.00000001)['hex'] print("Transaction sending... " + tx1) time.sleep(10) tx1_hash = broadcast(tx1) dest_addr_bytes = bytes(segwit_addr.decode(pref, dest_addr)[1]) tx1_parse = el.getTransaction(bytes.fromhex(tx1))[1] target_out = list( filter(lambda x: x.script == b'\x00\x20' + el.sha256(script), tx1_parse.txouts))[0] target_out_index = list.index(tx1_parse.txouts, target_out) tx2_parse = el.TransactionSegwit( 2, 0, 1, [el.Txin(bytes.fromhex(tx1_hash), target_out_index, b'', 0xFFFFFFFF)], [el.Txout(final_amount, b'\x00\x14' + dest_addr_bytes)], [[script]], 0) tx2 = el.putTransaction(b'', tx2_parse).hex() print("Transaction sending... " + tx2) time.sleep(10) broadcast(tx2)
def address(self, testnet=False): '''Returns the address corresponding to the script''' sig_type = self.type() if sig_type == 'p2pkh': # hash160 is the 3rd element h160 = self.elements[2] # convert to p2pkh address using h160_to_p2pkh_address (remember testnet) return h160_to_p2pkh_address(h160, testnet) elif sig_type == 'p2sh': # hash160 is the 2nd element h160 = self.elements[1] # convert to p2sh address using h160_to_p2sh_address (remember testnet) return h160_to_p2sh_address(h160, testnet) elif sig_type == 'p2pk': return h160_to_p2pkh_address(hash160(self.elements[0]), testnet) elif sig_type == 'p2wpkh': import segwit_addr if self.elements[0] == b'': witver = 0 else: assert 0 return segwit_addr.encode("bc", witver, self.elements[1])
def test_invalid_address_enc(self): """Test whether address encoding fails on invalid input.""" for hrp, version, length in INVALID_ADDRESS_ENC: code = segwit_addr.encode(hrp, version, [0] * length) self.assertIsNone(code)
from segwit_addr import encode from segwit_addr import decode from hash_util import hash160,hash256 hrp='tb' #testnet #hrp='bc' #mainnet pubkey1='21026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf3' pubkey2='2103befa190c0c22e2f53720b1be9476dcf11917da4665c44c9c71c3a2d28a933c35' pubkey3='2102be46dc245f58085743b1cc37c82f0d63a960efa43b5336534275fc469b49f4ac' data='52'+pubkey1+pubkey2+pubkey3+'53'+'ae' script_hash=hash256(data.decode('hex')).encode('hex') witver=0 witprog=[int(x) for x in bytearray.fromhex(script_hash)] #print witprog address=encode(hrp, witver, witprog) print address data=decode(hrp, address) #print data
def hash_to_segwit_addr(h): return segwit_addr.encode(NetworkConstants.SEGWIT_HRP, 0, h)
# Create script address from this pubkey # \x51 is OP_TRUE # \xae is OP_MULTICHECKSIG public_key = get_public_key(privkey, True) script = b'\x51' + bytes(chr(len(public_key)), 'ascii') + public_key + b'\x51' + b'\xae' addr_sha256 = sha256(script) addr_ripemd160_p2sh = ripemd160(addr_sha256) extended_ripemd160 = prefix_script + addr_ripemd160_p2sh check = sha256(extended_ripemd160) check = sha256(check) addr = extended_ripemd160 + check[:4] addr = base58.b58encode(addr) print("Redeem script: %s" % script.hex()) print("Public script address: %s" % addr) sys.path.append(os.path.abspath(".")) import segwit_addr # tb for testnet, bc for mainnet bc32 = segwit_addr.encode("tb", 0, addr_ripemd160) print("bech32 (p2wpkh): %s" % bc32) bc32 = segwit_addr.encode("tb", 0, addr_sha256) print("bech32 (p2wsh): %s" % bc32)
def elm_sig(command_set, text, dest_addr, coeff=10, len_offset=100, final_amount=1000): payto = command_set['payto'] broadcast = command_set['broadcast'] createnewaddress = command_set['createnewaddress'] getprivatekeys = command_set['getprivatekeys'] pref = dest_addr[:2] tmp_addr = createnewaddress() tmp_addr_bytes = bytes(segwit_addr.decode(pref, tmp_addr)[1]) script = el.putPushdata( b"", text.encode()) + b"\x75\x76\xA9\x14" + tmp_addr_bytes + b"\x88\xAC" init_amount = coeff * (len(script) + len_offset) + final_amount dest_script = segwit_addr.encode(pref, 0, el.sha256(script)) tx1 = payto(dest_script, init_amount * 0.00000001)['hex'] print("Transaction sending... " + tx1) time.sleep(10) tx1_hash = broadcast(tx1) dest_addr_bytes = bytes(segwit_addr.decode(pref, dest_addr)[1]) tx1_parse = el.getTransaction(bytes.fromhex(tx1))[1] target_out = list( filter(lambda x: x.script == b'\x00\x20' + el.sha256(script), tx1_parse.txouts))[0] target_out_index = list.index(tx1_parse.txouts, target_out) hashtype = el.SIGHASH_ALL tx2_in = [ el.Txin(bytes.fromhex(tx1_hash), target_out_index, b'', 0xFFFFFFFF) ] tx2_out = [el.Txout(final_amount, b'\x00\x14' + dest_addr_bytes)] tx2_parse = el.TransactionSegwit(2, 0, 1, tx2_in, tx2_out, [[script]], 0) txdigest = el.witness_digest(tx2_parse, hashtype, 0, init_amount, b'\x00\x20' + el.sha256(script), script) txsign = sign_tx_hash( txdigest, bitcoin.deserialize_privkey(getprivatekeys(tmp_addr))[1], hashtype) tx2_parse_signed = el.TransactionSegwit(2, 0, 1, tx2_in, tx2_out, [[txsign[1], txsign[0], script]], 0) tx2 = el.putTransaction(b'', tx2_parse_signed).hex() print("Transaction sending... " + tx2) time.sleep(10) broadcast(tx2)
def parse_ldb(fin_name, version=0.15, types=(0, 1, 28)): counter = 0 if 0.08 <= version < 0.15: prefix = b'c' elif version < 0.08: raise Exception("The utxo decoder only works for version 0.08 onwards.") else: prefix = b'C' # Open the LevelDB db = plyvel.DB(fin_name, compression=None) # Change with path to chainstate # Load obfuscation key (if it exists) o_key = db.get((unhexlify("0e00") + "obfuscate_key")) # If the key exists, the leading byte indicates the length of the key (8 byte by default). If there is no key, # 8-byte zeros are used (since the key will be XORed with the given values). if o_key is not None: o_key = hexlify(o_key)[2:] # For every UTXO (identified with a leading 'c'), the key (tx_id) and the value (encoded utxo) is displayed. # UTXOs are obfuscated using the obfuscation key (o_key), in order to get them non-obfuscated, a XOR between the # value and the key (concatenated until the length of the value is reached) if performed). not_decoded = [0, 0] for key, o_value in db.iterator(prefix=prefix): key = hexlify(key) if o_key is not None: value = deobfuscate_value(o_key, hexlify(o_value)) else: value = hexlify(o_value) # If the decode flag is passed, we also decode the utxo before storing it. This is really useful when running # a full analysis since will avoid decoding the whole utxo set twice (once for the utxo and once for the tx # based analysis) if version < 0.15: value = decode_utxo_v08_v014(value) else: value = decode_utxo(value, key, version) for out in value['outs']: # 0 --> P2PKH # 1 --> P2SH # 2 - 3 --> P2PK(Compressed keys) # 4 - 5 --> P2PK(Uncompressed keys) # 28 --> Bech32 if counter % 100 == 0: sys.stdout.write('\r parsed transactions: %d' % counter) sys.stdout.flush() counter += 1 if out['out_type'] == 0: if out['out_type'] not in types: continue add = hash_160_to_btc_address(out['data'], 0) yield add, out['amount'], value['height'] elif out['out_type'] == 1: if out['out_type'] not in types: continue add = hash_160_to_btc_address(out['data'], 5) yield add, out['amount'], value['height'] elif out['out_type'] in (2, 3, 4, 5): if out['out_type'] not in types: continue add = 'P2PK' yield add, out['amount'], value['height'] elif out['out_type'] == 28: if out['out_type'] not in types: continue ba1 = bytearray.fromhex(out['data']) add = segwit_addr.encode(hrp="bc", witver=0, witprog=bytearray(ba1[2:])) yield add, out['amount'], value['height'] else: print(value) not_decoded[0] += 1 not_decoded[1] += out['amount'] print('\nunable to decode %d transactions' % not_decoded[0]) print('totaling %d satoshi' % not_decoded[1]) db.close()
for code in ['b32', 'b58']: for ln in range(1, 90, 7): vector = (pat * (1 + (ln // 32)))[0:ln] enc = eval(f'{code}encode(vector)') print(f'# len={ln}', file=fd) print(f'assert {vector!r} == {code}decode({enc!r}), "fail @ {ln}"', file=fd) print( f'assert {vector!r} == {code}decode({code}encode({vector!r})), "fail @ {ln}"', file=fd) print(f'\nif ngu:\n msg = {pat!r}', file=fd) for hrp in ['bc', 'tb']: for ver in [0, 1, 15]: for alen in [20, 32]: msg = pat[:alen] exp = segwit_addr.encode(hrp, ver, msg) print( f' assert ngu.codecs.segwit_decode({exp!r}) == ({hrp!r}, {ver}, msg[0:{alen}])', file=fd) print( f' assert ngu.codecs.segwit_encode({hrp!r}, {ver}, msg[0:{alen}]) == {exp!r}', file=fd) print("print('PASS - %s')" % fd.name, file=fd) print("run code now in: %s" % fd.name) print('PASS - test_codecs')
def script_decoder(ScriptPubKey): #Hex input # #Pay_To_Pubkey if (ScriptPubKey[0:1] == b'\x41' and ScriptPubKey[-1:] == b'\xac'): # 41:65 byte is the size of public key. ac: OP_CHECKSIG Pubkey = ScriptPubKey[1:-1] # x = Pubkey[1:33] # y = Pubkey[33:] # print(len(Pubkey[1:]), binascii.hexlify(Pubkey[1:])) # print(len(x), "x: ", binascii.hexlify(x)) # print(len(y), "y: ", binascii.hexlify(y), int(binascii.hexlify(y), 16)%2) # if (int(binascii.hexlify(y), 16)%2): # prefix = b'\x03' # else: # prefix = b'\x02' # compressed_pubkey = prefix + x; # # compressed_pubkey = b'\x0c4f00a8aa87f595b60b1e390f17fc64d12c1a1f505354a7eea5f2ee353e427b72\x3c\xba\x1f\x4d\x12\xd1\xce\x0b\xce\xd7\x25\x37\x37\x69\xb2\x26\x2c\x6d\xaa\x97\xbe\x6a\x05\x88\xcf\xec\x8c\xe1\xa5\xf0\xbd\x0009' # print("compressed_pubkey: ", binascii.hexlify(compressed_pubkey)) h = hashlib.new('ripemd160') h.update(sha256(Pubkey).digest()) Hash160_Pubkey = h.digest() # ripemd160(sha256(Pubkey).digest()).digest() checksum = sha256(sha256(b'\x00'+Hash160_Pubkey).digest()).digest() # print(base58.b58encode(b'\x00'+Hash160_Pubkey+checksum[0:4])) # Pubkey : 04..., 04 means uncompressed public key Address = base58.b58encode(b'\x00'+Hash160_Pubkey+checksum[0:4]).decode("utf-8") # print(Address) _outfile.write( Address + os.linesep) # raise RuntimeError('ScriptPubKey') #Pay_To_Script_Hash elif (ScriptPubKey[0:2] == b'\xa9\x14' and ScriptPubKey[-1:] == b'\x87'): # a9:OP_HASH160, 14: 20bytes to push, 87:OP_EQUAL Hash160_Script = ScriptPubKey[2:-1] checksum = sha256(sha256(b'\x05'+Hash160_Script).digest()).digest() # print(base58.b58encode(b'\x05'+Hash160_Script+checksum[0:4])) Address = base58.b58encode(b'\x05'+Hash160_Script+checksum[0:4]).decode("utf-8") # print(Address) _outfile.write(Address + os.linesep) #Pay_To_PubkeyHash elif (ScriptPubKey[0:3] == b'\x76\xa9\x14' and ScriptPubKey[-2:] == b'\x88\xac'): #76:OP_DUP, a9:OP_HASH160, 14: 20bytes to push, 88:OP_EQUALVERIFY, ac: OP_CHECKSIG Hash160_Pubkey = ScriptPubKey[3:-2] checksum = sha256(sha256(b'\x00'+Hash160_Pubkey).digest()).digest() # print(binascii.hexlify(checksum[0:4])) # print(base58.b58encode(b'\x00'+Hash160_Pubkey+checksum[0:4])) Address = base58.b58encode(b'\x00'+Hash160_Pubkey+checksum[0:4]).decode("utf-8") _outfile.write(Address + os.linesep) elif (ScriptPubKey[0:1] == b'\x6a'): Data = ScriptPubKey[2:] # print("Return Operation") _outfile.write("Return Operation" + os.linesep) elif (ScriptPubKey[0:1] == b'\x00'): # I just handled Bech32 version 0 # print("ScriptPubKey: ", binascii.hexlify(ScriptPubKey)) ScriptPubKey_array = [x for x in ScriptPubKey[2:]] # print("ScriptPubKey_array: ", ScriptPubKey_array) Address = encode('bc',0,ScriptPubKey_array) # print("Address: ", Address) _outfile.write(Address + os.linesep) if (ScriptPubKey[1:2] != b'\x20' and ScriptPubKey[1:2] != b'\x14'): print(binascii.hexlify(ScriptPubKey[1:2])) raise Exception('Error in Bech32 detected') else: # print("other") _outfile.write("Other" + os.linesep)
def hash_to_segwit_addr(h, witver, *, net=None): if net is None: net = constants.net return segwit_addr.encode(net.SEGWIT_HRP, witver, h)