示例#1
0
    def to_seed(self, words, password='', validate=True):
        """
        Use Mnemonic words and optionally a password to create a PBKDF2 seed (Password-Based Key Derivation Function 2)
        
        First use 'sanitize_mnemonic' to determine language and validate and check words

        >>> from bitcoinlib.encoding import to_hexstring
        >>> to_hexstring(Mnemonic().to_seed('chunk gun celery million wood kite tackle twenty story episode raccoon dutch'))
        '6969ed4666db67fc74fae7869e2acf3c766b5ef95f5e31eb2fcebd93d76069c6de971225f700042b0b513f0ad6c8562277fc4b5ee1344b720f1686dc2dccc220'

        :param words: Mnemonic passphrase as string with space separated words
        :type words: str
        :param password: A password to protect key, leave empty to disable
        :type password: str
        :param validate: Validate checksum for given word phrase, default is True
        :type validate: bool
        
        :return bytes: PBKDF2 seed
        """
        words = self.sanitize_mnemonic(words)
        # Check if passphrase is valid
        if validate:
            self.to_entropy(words)
        mnemonic = to_bytes(words)
        password = to_bytes(password)
        return hashlib.pbkdf2_hmac(hash_name='sha512',
                                   password=mnemonic,
                                   salt=b'mnemonic' + password,
                                   iterations=2048)
示例#2
0
    def to_mnemonic(self, data, add_checksum=True, check_on_curve=True):
        """
        Convert key data entropy to Mnemonic sentence

        >>> Mnemonic().to_mnemonic('28acfc94465fd2f6774759d6897ec122')
        'chunk gun celery million wood kite tackle twenty story episode raccoon dutch'

        :param data: Key data entropy
        :type data: bytes, hexstring
        :param add_checksum: Included a checksum? Default is True
        :type add_checksum: bool
        :param check_on_curve: Check if data integer value is on secp256k1 curve. Should be enabled when not testing and working with crypto
        :type check_on_curve: bool
        
        :return str: Mnemonic passphrase consisting of a space seperated list of words
        """
        data = to_bytes(data)
        data_int = change_base(data, 256, 10)
        if check_on_curve and not 0 < data_int < secp256k1_n:
            raise ValueError(
                "Integer value of data should be in secp256k1 domain between 1 and secp256k1_n-1"
            )
        if add_checksum:
            binresult = change_base(data_int, 10, 2,
                                    len(data) * 8) + self.checksum(data)
            wi = change_base(binresult, 2, 2048)
        else:
            wi = change_base(data_int, 10, 2048,
                             len(data) // 1.375 + len(data) % 1.375 > 0)
        return normalize_string(' '.join([self._wordlist[i] for i in wi]))
示例#3
0
    def sendrawtransaction(self, rawtx):
        """
        Dummy method to send transactions on the bitcoinlib testnet. The bitcoinlib testnet does not exists,
        so it just returns the transaction hash.

        :param rawtx: A raw transaction hash
        :type rawtx: bytes, str

        :return str: Transaction hash
        """
        txid = to_hexstring(hashlib.sha256(hashlib.sha256(to_bytes(rawtx)).digest()).digest()[::-1])
        return {
            'txid': txid,
            'response_dict': {}
        }
示例#4
0
    def checksum(data):
        """
        Calculates checksum for given data key

        :param data: key string
        :type data: bytes, hexstring
        
        :return str: Checksum of key in bits
        """
        data = to_bytes(data)
        if len(data) % 4 > 0:
            raise ValueError(
                'Data length in bits should be divisible by 32, but it is not (%d bytes = %d bits).'
                % (len(data), len(data) * 8))
        key_hash = hashlib.sha256(data).digest()
        return change_base(key_hash, 256, 2, 256)[:len(data) * 8 // 32]
示例#5
0
    def wif_prefix(self,
                   is_private=False,
                   witness_type='legacy',
                   multisig=False):
        """
        Get WIF prefix for this network and specifications in arguments

        >>> Network('bitcoin').wif_prefix()  # xpub
        b'\\x04\\x88\\xb2\\x1e'
        >>> Network('bitcoin').wif_prefix(is_private=True, witness_type='segwit', multisig=True)  # Zprv
        b'\\x02\\xaaz\\x99'

        :param is_private: Private or public key, default is True
        :type is_private: bool
        :param witness_type: Legacy, segwit or p2sh-segwit
        :type witness_type: str
        :param multisig: Multisignature or single signature wallet. Default is False: no multisig
        :type multisig: bool

        :return bytes:
        """
        script_type = script_type_default(witness_type,
                                          multisig,
                                          locking_script=True)
        if script_type == 'p2sh' and witness_type in ['p2sh-segwit', 'segwit']:
            script_type = 'p2sh_p2wsh' if multisig else 'p2sh_p2wpkh'
        if is_private:
            ip = 'private'
        else:
            ip = 'public'
        found_prefixes = [
            to_bytes(pf[0]) for pf in self.prefixes_wif
            if pf[2] == ip and script_type == pf[5]
        ]
        if found_prefixes:
            return found_prefixes[0]
        else:
            raise NetworkError("WIF Prefix for script type %s not found" %
                               script_type)