Beispiel #1
0
def valid_metamask_message(address, message, signature):
    #address = attrs['address']
    #message = attrs['msg']
    #signature = attrs['signed_msg']

    r = int(signature[0:66], 16)
    s = int(add_0x_prefix(signature[66:130]), 16)
    v = int(add_0x_prefix(signature[130:132]), 16)
    if v not in (27, 28):
        v += 27

    message_hash = defunct_hash_message(text=message)
    pubkey = ecrecover_to_pub(decode_hex(message_hash.hex()), v, r, s)
    signer_address = encode_hex(sha3(pubkey)[-20:])

    if signer_address != address.lower():
        raise ValidationError({'result': 'Incorrect signature'}, code=400)

    return True
Beispiel #2
0
def test_add_0x_prefix_rejects_non_text_types(value):
    with pytest.raises(TypeError):
        add_0x_prefix(value)
Beispiel #3
0
def test_add_0x_prefix(value, expected):
    actual = add_0x_prefix(value)
    assert actual == expected
Beispiel #4
0
    def post(self):
        """ Handle POST request """

        if not self.request.body:
            log.warning('Missing body')
            self.set_status(400)
            self.write_json({
                'success': False,
                'clicks': None,
                'token': '',
            })
            return

        req = json.loads(self.request.body)
        token = req.get('token')
        recipient = req.get('recipient')
        contract = req.get('contract')

        invalids = []
        if not is_valid_token(token):
            invalids.append('token')
        if not recipient or not is_address(recipient):
            invalids.append('recipient')
        if not contract or not is_address(contract):
            invalids.append('contract')

        recipient = Web3.toChecksumAddress(recipient)
        contract = Web3.toChecksumAddress(contract)

        if len(invalids) > 0:
            log.warning('Invalid input: {}'.format(', '.join(invalids)))

            self.set_status(400)
            self.write_json({
                'success': False,
                'clicks': None,
                'token': '',
                'message': 'Invalid input'
            })
            return

        # Verify it exists
        clicks = rgetint(self.redis, token, 0)

        if not clicks:
            log.warning('Token has no clicks')
            self.write_json({
                'success': False,
                'clicks': None,
                'token': token,
                'message': 'Try clicking first'
            })
            return

        log.info('create_claim({}, {}, {}, {})'.format(recipient,
                                                       add_0x_prefix(token),
                                                       clicks * int(1e18),
                                                       contract))

        # Assemble claim
        claim = create_claim(recipient, add_0x_prefix(token),
                             clicks * int(1e18), contract)
        prefixed_claim_hash = defunct_hash_message(claim)
        # Docstring for this function sugests this does not prefix messages, so
        # we're prefixing above
        signed = self.accounts.eth_account.signHash(
            prefixed_claim_hash, self.signer_account_privkey)

        self.write_json({
            'success': True,
            'clicks': clicks,
            'token': token,
            'claim': claim.hex(),
            'signature': signed.signature.hex(),
            'contract': contract,
        })