コード例 #1
0
    def sign_message(self, signable_message: SignableMessage, private_key):
        r"""
        Sign the provided message.

        This API supports any messaging format that will encode to EIP-191_ messages.

        If you would like historical compatibility with
        :meth:`w3.eth.sign() <web3.eth.Eth.sign>`
        you can use :meth:`~eth_account.messages.encode_defunct`.

        Other options are the "validator", or "structured data" standards. (Both of these
        are in *DRAFT* status currently, so be aware that the implementation is not
        guaranteed to be stable). You can import all supported message encoders in
        ``eth_account.messages``.

        :param signable_message: the encoded message for signing
        :param private_key: the key to sign the message with
        :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey`
        :returns: Various details about the signature - most importantly the fields: v, r, and s
        :rtype: ~eth_account.datastructures.SignedMessage

        .. doctest:: python

            >>> msg = "I♥SF"
            >>> from eth_account.messages import encode_defunct
            >>> msghash = encode_defunct(text=msg)
            >>> msghash
            SignableMessage(version=b'E',
             header=b'thereum Signed Message:\n6',
             body=b'I\xe2\x99\xa5SF')
            >>> # If you're curious about the internal fields of SignableMessage, take a look at EIP-191, linked above  # noqa: E501
            >>> key = "0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364"
            >>> Account.sign_message(msghash, key)
            SignedMessage(messageHash=HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'),
             r=104389933075820307925104709181714897380569894203213074526835978196648170704563,
             s=28205917190874851400050446352651915501321657673772411533993420917949420456142,
             v=28,
             signature=HexBytes('0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'))



        .. _EIP-191: https://eips.ethereum.org/EIPS/eip-191
        """
        message_hash = _hash_eip191_message(signable_message)
        return self._sign_hash(message_hash, private_key)
コード例 #2
0
    def get_ecrecover(self,
                      signedData: str,
                      data: str = None,
                      dataHash: str = None):
        """
        Get address associated with the signature (ecrecover)
        """
        if (data is None) and (dataHash is None):
            cprint(
                "Missing Argument, either 'dataHash' or 'data' must be passed?",
                "red")
            return 0

        try:
            if data is not None:
                from eth_account.messages import encode_defunct, _hash_eip191_message

                hex_message_hash = w3.toHex(
                    _hash_eip191_message(encode_defunct(hexstr=data)))
            elif dataHash is not None:
                hex_message_hash = dataHash

            sig = w3.toBytes(hexstr=signedData)
            v, hex_r, hex_s = (
                w3.toInt(sig[-1]),
                w3.toHex(sig[:32]),
                w3.toHex(sig[32:64]),
            )
            address = w3.eth.account.recoverHash(hex_message_hash,
                                                 signature=sig)
            # TODO: verify this! seems that sometimes it returns wrong address
            # test with :
            #           data="0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
            #           signedData="0xe7225f986f192f859a9bf84e34b2b7001dfa11aeb5c7164f81a2bee0d79943e2587be1faa11502eba0f803bb0ee071a082b6fe40fba025f3309263a1eef52c711c"
            #       Correct address: 0xb60e8dd61c5d32be8058bb8eb970870f07233155  //based on https://wiki.parity.io/JSONRPC-personal-module.html#personal_ecrecover
            #       Returned address: 0x02F0D4b967a73D6907a221DB6106446F1d3d4CDB

            cprint("Address: {}".format(address),
                   "green")  # TODO: make this print pretty json
            cprint("r: {}\ns: {}\nv: {} ".format(hex_r, hex_s, v), "white")
        except Exception as e:
            cprint("failed to get address: {} \n".format(e), "yellow")
コード例 #3
0
    def recover_message(self, signable_message: SignableMessage, vrs=None, signature=None):
        r"""
        Get the address of the account that signed the given message.
        You must specify exactly one of: vrs or signature

        :param signable_message: the message that was signed
        :param vrs: the three pieces generated by an elliptic curve signature
        :type vrs: tuple(v, r, s), each element is hex str, bytes or int
        :param signature: signature bytes concatenated as r+s+v
        :type signature: hex str or bytes or int
        :returns: address of signer, hex-encoded & checksummed
        :rtype: str

        .. doctest:: python

            >>> from eth_account.messages import encode_defunct
            >>> from eth_account import Account
            >>> message = encode_defunct(text="I♥SF")
            >>> vrs = (
            ...   28,
            ...   '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
            ...   '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
            >>> Account.recover_message(message, vrs=vrs)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'


            # All of these recover calls are equivalent:

            # variations on vrs
            >>> vrs = (
            ...   '0x1c',
            ...   '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3',
            ...   '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce')
            >>> Account.recover_message(message, vrs=vrs)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'

            >>> # Caution about this approach: likely problems if there are leading 0s
            >>> vrs = (
            ...   0x1c,
            ...   0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3,
            ...   0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce)
            >>> Account.recover_message(message, vrs=vrs)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'

            >>> vrs = (
            ...   b'\x1c',
            ...   b'\xe6\xca\x9b\xbaX\xc8\x86\x11\xfa\xd6jl\xe8\xf9\x96\x90\x81\x95Y8\x07\xc4\xb3\x8b\xd5(\xd2\xcf\xf0\x9dN\xb3',  # noqa: E501
            ...   b'>[\xfb\xbfM>9\xb1\xa2\xfd\x81jv\x80\xc1\x9e\xbe\xba\xf3\xa1A\xb29\x93J\xd4<\xb3?\xce\xc8\xce')  # noqa: E501
            >>> Account.recover_message(message, vrs=vrs)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'

            # variations on signature
            >>> signature = '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'  # noqa: E501
            >>> Account.recover_message(message, signature=signature)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
            >>> signature = b'\xe6\xca\x9b\xbaX\xc8\x86\x11\xfa\xd6jl\xe8\xf9\x96\x90\x81\x95Y8\x07\xc4\xb3\x8b\xd5(\xd2\xcf\xf0\x9dN\xb3>[\xfb\xbfM>9\xb1\xa2\xfd\x81jv\x80\xc1\x9e\xbe\xba\xf3\xa1A\xb29\x93J\xd4<\xb3?\xce\xc8\xce\x1c'  # noqa: E501
            >>> Account.recover_message(message, signature=signature)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
            >>> # Caution about this approach: likely problems if there are leading 0s
            >>> signature = 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c  # noqa: E501
            >>> Account.recover_message(message, signature=signature)
            '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
        """
        message_hash = _hash_eip191_message(signable_message)
        return self._recover_hash(message_hash, vrs, signature)
コード例 #4
0
def test_hashed_structured_data(message_encodings):
    structured_msg = encode_structured_data(**message_encodings)
    hashed_structured_msg = _hash_eip191_message(structured_msg)
    expected_hash_value_hex = "4e3c4173651b3054c0635dfae57a3b65ae1527ed0ba9ff76cecb6d9807687a7f"
    assert hashed_structured_msg.hex() == expected_hash_value_hex
コード例 #5
0
 def msg_hash(self):
     return _hash_eip191_message(self.msg)
コード例 #6
0
def test_hashed_structured_data(message_encodings):
    structured_msg = encode_structured_data(**message_encodings)
    hashed_structured_msg = _hash_eip191_message(structured_msg)
    expected_hash_value_hex = "be609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"
    assert hashed_structured_msg.hex() == expected_hash_value_hex