    async def start_verification(self, client_id, username):
        async with self.lock:
            await self.db.execute('SELECT code FROM scratchverifier_usage WHERE \
client_id=? AND username=?', (client_id, username))
            row = await self.db.fetchone()
        if row is not None:
            await self.db.execute('UPDATE scratchverifier_usage SET expiry=? \
WHERE client_id=? AND username=? AND code=?', (int(time.time()) + VERIFY_EXPIRY,
                                               client_id, username, row[0]))
            return row[0]
        code = sha256(
            str(client_id).encode()
            + str(time.time()).encode()
            + username.encode()
            + token_bytes()
        # 0->A, 1->B, etc, to avoid Scratch's phone number censor
        ).hexdigest().translate({ord('0') + i: ord('A') + i for i in range(10)})
        await self.db.execute('INSERT INTO scratchverifier_usage (client_id, \
code, username, expiry) VALUES (?, ?, ?, ?)', (client_id, code, username,
                               int(time.time() + VERIFY_EXPIRY)))
        await self.db.execute('INSERT INTO scratchverifier_logs (client_id, \
username, log_time, log_type) VALUES (?, ?, ?, ?)', (client_id, username,
                                                     int(time.time()), 1))
        await self.db.execute('DELETE FROM scratchverifier_usage WHERE \
expiry<=?', (int(time.time()),))
        return code
When an actor claims to have a given identity, the software does not prove or insufficiently proves that the claim is correct.