We present a general purpose, privacy-preserving framework for verifying user attributes. The framework is designed for users (e.g., a job candidate) to allow a challenger (e.g., a prospective employer) to verify whether the user meets a particular requirement (e.g., does the candidate hold a valid driving license?), without leaking any other information about the user. Importantly, the user is an active part of the challenge-verification process, which ensures that challenges cannot be made without the user's full knowledge and participation. The framework is decentralized and requires a public blockchain. A smart contract is used to manage the challenge-verification process, and zero-knowledge proofs are used to verify challenges in a privacy-preserving manner. We implement a simplified version of the framework using smart contracts deployed on the Ethereum blockchain, and we simulate some simple use cases. All simulation code is available open-source (https://github.com/lifeisbeer/BlockVerify).