solve a particular denial-of-service issue such as the spam problem is subject to debate; the system must make sending spam emails obtrusively unproductive for the spammer, but should also not prevent legitimate users from sending their messages. In other words, a genuine user should not encounter any difficulties when sending an email, but an email spammer would have to expend a considerable amount of computing power to send out many emails at once. Proof-of-work systems are being used by other, more complex cryptographic systems such as bitcoin, which uses a system similar to Hashcash. Variants There are two classes of proof-of-work protocols. Challenge–response protocols assume a direct interactive link between the requester (client) and the provider (server). The provider chooses a challenge, say an item in a set with a property, the requester finds the relevant response in the set, which is sent back and checked by the provider. As the challenge is chosen on the spot by the provider, its difficulty can be adapted to its current load. The work on the requester side may be bounded if the challenge-response protocol has a known solution (chosen by the provider), or is known to exist within a bounded search space. Solution–verification protocols do not assume such a link: as a result, the problem must be self-imposed before a solution is sought by the requester, and the provider must check both the problem choice and the found solution. Most such schemes are unbounded probabilistic iterative procedures such as Hashcash. Known-solution protocols tend to have slightly lower variance than unbounded probabilistic protocols because the variance of a rectangular distribution is lower than the variance of a Poisson distribution (with the same mean). A generic technique for reducing variance is to use multiple independent sub-challenges, as the average of multiple samples will have a lower variance. There are also fixed-cost functions such as the time-lock puzzle. Moreover, the underlying functions used by these schemes may be: CPU-bound where the computation runs at the speed of the processor, which greatly varies in time, as well as from high-end server to low-end portable devices. Memory-bound where the computation speed is bound by main memory accesses (either latency or bandwidth), the performance of which is expected to be less sensitive to hardware evolution. Network-bound if the client must perform few computations, but must collect some tokens from remote servers before querying the final service provider. In