Exemplo n.º 1
0
    def is_valid_contract_sig(self, contract, node_id=None):
        sig = contract[u"signature"][:]
        del contract[u"signature"]

        if sys.version_info >= (3, 0, 0):
            msg = str(contract).encode("ascii")
        else:
            msg = str(contract)

        # Use our address.
        msg = binascii.hexlify(msg).decode("utf-8")
        if node_id is None:
            address = self.wallet.get_address(self.wif)
            ret = self.wallet.verify_signature(address, sig, msg)
        else:
            # Use their node ID: try testnet.
            address = b2a_hashed_base58(b'o' + node_id)
            ret = self.wallet.verify_signature(address, sig, msg)
            if not ret:
                # Use their node ID: try mainnet.
                address = b2a_hashed_base58(b'\0' + node_id)
                ret = self.wallet.verify_signature(address, sig, msg)

        # Move sig back.
        contract[u"signature"] = sig[:]

        return ret
Exemplo n.º 2
0
def render_address(script, testnet=True):
    # take a scriptPubKey (part of the TxOut) and convert into conventional human-readable
    # string... aka: the "payment address"
    from pycoin.encoding import b2a_hashed_base58
    from pycoin.contrib.segwit_addr import encode as bech32_encode

    ll = len(script)

    if not testnet:
        bech32_hrp = 'bc'
        b58_addr = bytes([0])
        b58_script = bytes([5])
    else:
        bech32_hrp = 'tb'
        b58_addr = bytes([111])
        b58_script = bytes([196])

    # P2PKH
    if ll == 25 and script[0:3] == b'\x76\xA9\x14' and script[
            23:26] == b'\x88\xAC':
        return b2a_hashed_base58(b58_addr + script[3:3 + 20])

    # P2SH
    if ll == 23 and script[0:2] == b'\xA9\x14' and script[22] == 0x87:
        return b2a_hashed_base58(b58_script + script[2:2 + 20])

    # P2WPKH
    if ll == 22 and script[0:2] == b'\x00\x14':
        return bech32_encode(bech32_hrp, 0, script[2:])

    # P2WSH
    if ll == 34 and script[0:2] == b'\x00\x20':
        return bech32_encode(bech32_hrp, 0, script[2:])

    return '[script: %s]' % b2a_hex(script)
Exemplo n.º 3
0
    def fromPrivkey(cls, ecdsaPrivkey):
        """Returns a new Address object from the private key.
        The private key can be used to get the public key,
        hence the need only for the private key.
        """
        rawPrivkey = cls.PRIVATE_KEY_PREFIX + ecdsaPrivkey.to_string()
        privkey = b2a_hashed_base58(rawPrivkey)

        ecdsaPubkey = ecdsaPrivkey.get_verifying_key()
        rawPubkey = cls.PUBLIC_KEY_PREFIX + hash160(
            "\x04" + ecdsaPubkey.to_string())
        pubkey = b2a_hashed_base58(rawPubkey)

        return cls(pubkey, privkey)
Exemplo n.º 4
0
def make_ms_address(M, keys, idx=0, is_change=0, addr_fmt=AF_P2SH, testnet=1, **make_redeem_args):
    # Construct addr and script need to represent a p2sh address
    import bech32
    from pycoin.encoding import b2a_hashed_base58, hash160

    if 'path_mapper' not in make_redeem_args:
        make_redeem_args['path_mapper'] = lambda cosigner: [HARD(45), cosigner, is_change, idx]

    script, pubkeys, xfp_paths = make_redeem(M, keys, **make_redeem_args)

    if addr_fmt == AF_P2WSH:
        hrp = ['bc', 'tb'][testnet]
        data = sha256(script).digest()
        addr = bech32.encode(hrp, 0, data)
        scriptPubKey = bytes([0x0, 0x20]) + data
    else:
        if addr_fmt == AF_P2SH:
            digest = hash160(script)
        elif addr_fmt == AF_P2WSH_P2SH:
            digest = hash160(b'\x00\x20' + sha256(script).digest())
        else:
            raise ValueError(addr_fmt)

        prefix = bytes([196]) if testnet else bytes([5])
        addr = b2a_hashed_base58(prefix + digest)

        scriptPubKey = bytes([0xa9, 0x14]) + digest + bytes([0x87])

    return addr, scriptPubKey, script, zip(pubkeys, xfp_paths)
Exemplo n.º 5
0
 def get_data(self):
     """Get this object as a JSON/Storage compatible dict.
     Useful for storage and persistence.
     """
     raw = self.prefix + to_bytes_32(self.rawPrivKey)
     return {"color_set": self.color_set.get_data(),
             "address_data": b2a_hashed_base58(raw)}
Exemplo n.º 6
0
 def get_data(self):
     """Get this object as a JSON/Storage compatible dict.
     Useful for storage and persistence.
     """
     raw = self.prefix + to_bytes_32(self.rawPrivKey)
     return {
         "color_set": self.color_set.get_data(),
         "address_data": b2a_hashed_base58(raw)
     }
Exemplo n.º 7
0
def slip132undo(orig):
    # take a SLIP-132 xpub/ypub/z/U/?pub/prv and convert into BIP-32 style
    # - preserve testnet vs. mainnet
    # - return addr fmt info
    from pycoin.encoding import a2b_hashed_base58, b2a_hashed_base58
    from ckcc_protocol.constants import AF_P2WPKH_P2SH, AF_P2SH, AF_P2WSH, AF_P2WSH_P2SH
    from ckcc_protocol.constants import AF_P2WPKH

    assert orig[0] not in 'xt', "already legit bip32"

    xpub = a2b_hex('0488B21E')
    tpub = a2b_hex('043587cf')
    xprv = a2b_hex('0488ADE4')
    tprv = a2b_hex('04358394')

    variants = [
        (False, AF_P2WPKH_P2SH, '049d7cb2', '049d7878', 'y'),
        (False, AF_P2WPKH, '04b24746', '04b2430c', 'z'),
        (False, AF_P2WSH_P2SH, '0295b43f', '0295b005', 'Y'),
        (False, AF_P2WSH, '02aa7ed3', '02aa7a99', 'Z'),
        (True, AF_P2WPKH_P2SH, '044a5262', '044a4e28', 'u'),
        (True, AF_P2WPKH, '045f1cf6', '045f18bc', 'v'),
        (True, AF_P2WSH_P2SH, '024289ef', '024285b5', 'U'),
        (True, AF_P2WSH, '02575483', '02575048', 'V'),
    ]

    raw = a2b_hashed_base58(orig)

    for testnet, addr_fmt, pub, priv, hint in variants:

        if raw[0:4] == a2b_hex(pub):
            return b2a_hashed_base58((tpub if testnet else xpub) + raw[4:]), \
                        testnet, addr_fmt, False

        if raw[0:4] == a2b_hex(priv):
            return b2a_hashed_base58((tprv if testnet else xprv) + raw[4:]), \
                        testnet, addr_fmt, True

    raise RuntimeError("unknown prefix")
Exemplo n.º 8
0
def p2sh_address(key):
    """
    Function to convert the given private key to the P2SH key
    used to signify a SegWit address starting with '3'.

    This SegWit address is a <redeemScript>
    (https://bitcoincore.org/en/segwit_wallet_dev/#creation-of-p2sh-p2wpkh-address).

    It starts with a OP_0, followed by a canonical push of the keyhash 
    (i.e. 0x0014{20-byte keyhash}).
    """
    return b2a_hashed_base58(b'\5' +
                             hash160(b'\x00\x14' +
                                     hash160(key.sec(use_uncompressed=False))))
Exemplo n.º 9
0
def scriptsig2adddr(scriptsig):
    if type(scriptsig) is not bytes:
        scriptsig = binascii.unhexlify(scriptsig)
    pos = 0
    ln = scriptsig[pos]
    pos += 1
    sig = sigscript[pos:pos + ln]
    pos += ln
    ln = scriptsig[pos]
    pos += 1
    pubkey = scriptsig[pos:pos + ln:]
    pubkeyhash = encoding.hash160(pubkey)
    r = encoding.b2a_hashed_base58(settings.PUB_PREFIX + pubkeyhash)
    return r
Exemplo n.º 10
0
def pkscript2addr(pkscript):
    if type(pkscript) is not bytes:
        pkscript = binascii.unhexlify(pkscript)
    # Pay-to-PubkeyHash
    if pkscript[:2] == b'\x76\xa9' and pkscript[-2:] == b'\x88\xac':
        ln = pkscript[2]
        pubkeyhash = pkscript[3:3 + ln]
        data = settings.PUB_PREFIX + pubkeyhash
        res = encoding.b2a_hashed_base58(data)
        return res
    # Pay-to-Script-Hash
    elif False:
        return 'TODO'
    # OP_RETURN
    elif pkscript[0] == b'\x6a':
        return 'null'
    return False
Exemplo n.º 11
0
def address_for_pay_to_script_wit(script, netcode=None):
    if netcode is None:
        netcode = get_current_netcode()
    address_prefix = pay_to_script_wit_prefix_for_netcode(netcode)
    return encoding.b2a_hashed_base58(address_prefix + b'\0\0' + hashlib.sha256(script).digest())
Exemplo n.º 12
0
    def getJSONData(self):
        """Returns a dict that can later be plugged into
        the fromObj method for later retrieval of an Address.
        This is particularly useful for storing/retrieving
        from a data store."""
        return {"pubkey": self.pubkey, "privkey": self.privkey}


class TestnetAddress(Address):
    """TestnetAddress represents a Bitcoin Testnet address.
    Be sure that bitcoind is running with the "-testnet" flag.
    """
    PUBLIC_KEY_PREFIX = "\x6F"
    PRIVATE_KEY_PREFIX = "\xEF"


if __name__ == "__main__":
    # test the key generation
    test_key = 'a' * 32
    address = Address.new(test_key)
    print address.pubkey
    rawPubkey = Address.PUBLIC_KEY_PREFIX + hash160(
        "\x04" + address.rawPubkey())
    print b2a_hashed_base58(rawPubkey)
    assert address.privkey \
        == "5JZB2s2RCtRUunKiqMbb6rAj3Z7TkJwa8zknL1cfTFpWoQArd6n", \
        "address generation isn't what was expected"

    assert address.rawPrivkey() == test_key, "wrong priv key"
Exemplo n.º 13
0
 def rawPubkeyToAddress(cls, raw):
     return b2a_hashed_base58(cls.PUBLIC_KEY_PREFIX + raw)
Exemplo n.º 14
0
def node_id_to_address(node_id):
    """Convert a node id to a bitcoin address."""
    return b2a_hashed_base58(b'\0' + node_id)
Exemplo n.º 15
0
def nodeid2address(hexnodeid):
    """Convert a node id to a bitcoin address."""
    nodeid = binascii.unhexlify(hexnodeid)
    return b2a_hashed_base58(b'\0' + nodeid)
 def do_test(as_text, as_bin):
     self.assertEqual(as_text, encoding.b2a_hashed_base58(as_bin))
     self.assertEqual(as_bin, encoding.a2b_hashed_base58(as_text))
     self.assertTrue(encoding.is_hashed_base58_valid(as_text))
     bogus_text = as_text[:-1] + chr(1+ord(as_text[-1]))
     self.assertFalse(encoding.is_hashed_base58_valid(bogus_text))
Exemplo n.º 17
0
def nodeid_to_address(nodeid):
    """Convert a node id to a bitcoin address."""
    return b2a_hashed_base58(b'\0' + nodeid)
Exemplo n.º 18
0
def pcode_b58(pcode):
    PREFIX = b'\x46'    # Spec recommends b'\x23'
    return b2a_hashed_base58( PREFIX + pcode )
Exemplo n.º 19
0
def btc_to_address(prefix, subkey):
    return b2a_hashed_base58(prefix + subkey.hash160())
Exemplo n.º 20
0
def dump(psbt, hex_output, bin_output, testnet, base64, show_addrs):

    raw = psbt.read()
    if raw[0:10] == b'70736274ff':
        raw = _a2b_hex(raw.strip())
    if raw[0:6] == b'cHNidP':
        raw = b64decode(raw)

    #assert raw[0:5] == b'psbt\xff'

    if hex_output:
        print(b2a_hex(raw))
        sys.exit(0)

    if base64:
        print(str(b64encode(raw), 'ascii'))
        sys.exit(0)

    print("%d bytes in PSBT: %s" % (len(raw), psbt.name))

    if bin_output:
        bin_output.write(raw)
        sys.exit(0)

    with io.BytesIO(raw) as fd:
        hdr = fd.read(4)
        sep1 = fd.read(1)

        print("-- HEADER --\n\n%s 0x%02x\n" % (str(hdr, 'ascii'), sep1[0]))

        print("-- GLOBALS --")
        num_ins = None
        num_outs = None
        section = 'globals'
        section_idx = 0
        expect_outs = set()

        while 1:
            first = fd.read(1)
            if first == b'':
                print("-- ACTUAL EOF --")
                break

            try:
                ks = deser_compact_size(fd, first[0])
            except:
                print("? confused at %d=0x%x" % (fd.tell(), fd.tell()))
                break

            if ks == 0:
                section_idx += 1

                if section == 'globals':
                    section_idx = 0
                    section = 'inputs'
                    print("-- INPUT #0 --")
                elif section == 'inputs':
                    if section_idx == num_ins:
                        print("-- OUTPUT #0 --")
                        section = 'outputs'
                        section_idx = 0
                    else:
                        print("-- INPUT #%d --" % section_idx)
                elif section == 'outputs':
                    if section_idx == num_outs:
                        print("-- EXPECT EOF --")
                        section = 'past eof'
                        section_idx = 0
                    else:
                        print("-- OUTPUT #%d --" % section_idx)
                else:
                    print("-- ?? %s ??  --" % section.upper())
                continue

            try:
                assert ks
                key = fd.read(ks)

                vs = deser_compact_size(fd)
                assert vs
                val = fd.read(vs)

            except:
                print("? confused at %d=0x%x" % (fd.tell(), fd.tell()))
                break

            try:
                if section == 'globals':
                    purpose = ['GLOBAL_UNSIGNED_TX', 'GLOBAL_XPUB'][key[0]]
                elif section == 'inputs':
                    purpose = [
                        'IN_NON_WITNESS_UTXO', 'IN_WITNESS_UTXO',
                        'IN_PARTIAL_SIG', 'IN_SIGHASH_TYPE',
                        'IN_REDEEM_SCRIPT', 'IN_WITNESS_SCRIPT',
                        'IN_BIP32_DERIVATION', 'IN_FINAL_SCRIPTSIG',
                        'IN_FINAL_SCRIPTWITNESS'
                    ][key[0]]
                elif section == 'outputs':
                    purpose = [
                        'OUT_REDEEM_SCRIPT', 'OUT_WITNESS_SCRIPT',
                        'OUT_BIP32_DERIVATION'
                    ][key[0]]

            except IndexError:
                purpose = 'Unknown type=0x%0x' % key[0]

            print('\n  key: %02x ' % key[0], end='')
            if len(key) <= 1:
                print("(%s)" % purpose)
            else:
                print('%s\n       (%s + %d bytes)' %
                      (b2a_hex(key[1:]), purpose, ks - 1))

            print('value: ', end='')

            if len(val) == 4 and key[0] != PSBT_GLOBAL_XPUB:
                nn, = struct.unpack("<I", val)
                print("'%s' = 0x%x = %d\n" % (b2a_hex(val), nn, nn))
                continue

            print('%s  (%d bytes)\n' % (b2a_hex(val), vs))

            # prefix byte for addresses in current network
            ADP = b'\x6f' if testnet else b'\0'

            if (section, key[0]) in [('globals', PSBT_GLOBAL_UNSIGNED_TX),
                                     ('inputs', PSBT_IN_NON_WITNESS_UTXO)]:
                # Parse and sumarize the bitcoin transaction.
                # - also works for non-witness UTXO

                try:
                    t = Tx.parse(io.BytesIO(val))
                    print(" Transaction: (%d inputs, %d outputs, %d witness)" %
                          (len(t.txs_in), len(t.txs_out),
                           sum(1 for i in t.txs_in if i.witness)))
                    print("            : txid %s" % t.hash())
                    for n, i in enumerate(t.txs_in):
                        print("   [in #%d] %s" %
                              (n,
                               i.address(ADP) if i.script else '(not signed)'))
                        if section == 'globals':
                            print("    from %s : %d" %
                                  (b2h_rev(i.previous_hash), i.previous_index))
                    for n, o in enumerate(t.txs_out):
                        out_addr = render_address(o.script, testnet)
                        print("  [out #%d] %.8f => %s" %
                              (n, o.coin_value / 1E8, out_addr))
                        expect_outs.add(out_addr)
                    print("\n")

                    if num_ins is None:
                        num_ins = len(t.txs_in)
                        num_outs = len(t.txs_out)
                except:
                    print("(unable to parse txn)")
                    raise

            if (section, key[0]) == ('globals', PSBT_GLOBAL_XPUB):
                # key is: binary BIP32 serialization (not base58)
                # value is: master key fingerprint catenated with the derivation path of public key

                fingerprint = val[0:4]
                if len(val) > 4:
                    path = [
                        struct.unpack_from('<I', val, offset=i)[0]
                        for i in range(4, len(val), 4)
                    ]
                    path = [
                        str(i & 0x7fffffff) + ("'" if i & 0x80000000 else "")
                        for i in path
                    ]
                else:
                    # valid: no subpath, just xfp.
                    path = []

                print("       XPUB: %s" % b2a_hashed_base58(key[1:]))
                print("    HD Path: (m=%s)/%s\n" %
                      (xfp2hex(fingerprint), '/'.join(path)))

            if (section, key[0]) in [('inputs', PSBT_IN_BIP32_DERIVATION),
                                     ('outputs', PSBT_OUT_BIP32_DERIVATION)]:
                # HD key paths
                try:
                    pubkey = key[1:]
                    fingerprint = val[0:4]
                    path = [
                        struct.unpack_from('<I', val, offset=i)[0]
                        for i in range(4, len(val), 4)
                    ]
                    path = [
                        str(i & 0x7fffffff) + ("'" if i & 0x80000000 else "")
                        for i in path
                    ]

                    # conservative: render them all, pick one found if expected
                    # - but not helpful for multisig, need to look around to know if thats the case
                    addrs = []
                    if show_addrs:
                        if len(pubkey) in {33, 65}:
                            # assume old skool b58 p2pkh, bitcoin mainnet, etc.
                            h20 = hash160(pubkey)
                            for prefix in [0, 111]:
                                addrs.append(
                                    b2a_hashed_base58(bytes([prefix]) + h20))
                            for hrp in ['bc', 'tb']:
                                addrs.append(bech32_encode(hrp, 0,
                                                           h20))  # really?

                        match = set(addrs).intersection(expect_outs)
                        if match:
                            addrs = list(match)

                    print("     Pubkey: %s (%d bytes)" %
                          (b2a_hex(pubkey), len(pubkey)))
                    print("    HD Path: (m=%s)/%s" %
                          (xfp2hex(fingerprint), '/'.join(path)))
                    for addr in addrs:
                        print("             = %s" % addr)
                    print("\n")
                except:
                    print("(unable to parse hdpath)")

            if (section, key[0]) in [('inputs', PSBT_IN_REDEEM_SCRIPT),
                                     ('inputs', PSBT_IN_WITNESS_SCRIPT),
                                     ('outputs', PSBT_OUT_REDEEM_SCRIPT),
                                     ('outputs', PSBT_OUT_WITNESS_SCRIPT)]:

                try:
                    if val[-1] == 0xAE and len(val) > 22:
                        M, N = (val[0] - 80, val[-2] - 80)
                        print("     P2SH Multisig: %d of %d" % (M, N))
                        print("     Pubkeys: ")
                        for idx in range(N):
                            pk = val[1 + (34 * idx):]
                            assert pk[0] == 0x21
                            print("        #%d: %s" %
                                  (idx + 1, b2a_hex(pk[1:1 + 33])))

                        exp = ((N * 34) + 3)
                        if len(val) > exp:
                            print("        (plus JUNK: %d bytes)" %
                                  (len(val) - exp))
                        print("\n")

                        # XXX decode implied p2sh addresses here too?
                except:
                    print("(unable to parse POSSIBLE multisig redeem script)")
Exemplo n.º 21
0
def btc_to_private(exponent):
    return b2a_hashed_base58(b'\x80' + to_bytes_32(exponent) + b'\01')
Exemplo n.º 22
0
def address_for_pay_to_script_wit(script, netcode=None):
    if netcode is None:
        netcode = get_current_netcode()
    address_prefix = pay_to_script_wit_prefix_for_netcode(netcode)
    return encoding.b2a_hashed_base58(address_prefix + b'\0\0' +
                                      hashlib.sha256(script).digest())
Exemplo n.º 23
0
print("\npycoin.key.Key example - ", my_netcode)

#print("Private Key (dec): ", eval('0x' + privkey_hex))
print("Private Key (dec): ", int(privkey_hex, 16))
print("Private Key (hex): ", privkey_hex)
privkey_bytes = unhexlify(privkey_hex)
# use CBitcoinSecret to compress private key
btc_secret = CBitcoinSecret.from_secret_bytes(privkey_bytes, True)
print("     compressed: ", hexlify(btc_secret.to_bytes()))
assert(btc_secret.is_compressed == True)
assert(bitcoin.core.b2x(btc_secret.to_bytes()) == (privkey_hex + '01'))

print("Private Key   WIF: ", my_key.wif())
print("     uncompressed: ", my_key.wif(use_uncompressed=True))

print("Privkey hashed base58: ", encoding.b2a_hashed_base58(privkey_bytes))


print()
## Public key and address
public_key = my_key.public_pair()
(public_key_x, public_key_y) = public_key

print("Public Key Pair: ", public_key)
print("     x as hex: ", hex(public_key[0]))
print("     y as hex: ", hex(public_key[1]))

#compressed_indicator_1 = '02' if (public_key_y % 2) == 0 else '03'
compressed_indicator = True if (public_key_y % 2) == 0 else False
print("Public key y parity: ", 'even' if compressed_indicator else 'odd')
assert(compressed_indicator != my_key._use_uncompressed)
Exemplo n.º 24
0
 def do_test(as_text, as_bin):
     self.assertEqual(as_text, encoding.b2a_hashed_base58(as_bin))
     self.assertEqual(as_bin, encoding.a2b_hashed_base58(as_text))
     self.assertTrue(encoding.is_hashed_base58_valid(as_text))
     bogus_text = as_text[:-1] + chr(1 + ord(as_text[-1]))
     self.assertFalse(encoding.is_hashed_base58_valid(bogus_text))