A decentralized user profile management system built with Solidity that allows users to register, update, and retrieve their profiles on the Ethereum blockchain.
- Overview
- Features
- Contract Structure
- Functions
- Events
- Getting Started
- Usage Examples
- Security Considerations
- License
The UserProfileRegistry contract provides a simple and secure way to store user profile information on the blockchain. Each Ethereum address can register one unique profile containing personal information such as name, email, age, and a custom user ID.
- User Registration: Register a new user profile with personal details
- Profile Updates: Modify existing profile information
- Profile Retrieval: Get profile data for any registered user
- Registration Verification: Check if a user is registered
- Event Logging: Track registration and update activities
- Access Control: Users can only update their own profiles
struct UserProfile {
uint256 userId; // Custom user identifier
uint256 age; // User's age
string name; // User's name
string email; // User's email address
uint256 registrationTimestamp; // When the profile was created
bool isRegistered; // Registration status
}mapping(address => UserProfile) public profiles- Stores user profilesmapping(address => bool) public isRegistered- Tracks registration status
function registerUser(string memory _name, uint256 _userId, uint256 _age, string memory _email) publicRegisters a new user profile. Each address can only register once.
Parameters:
_name: User's full name_userId: Custom user identifier_age: User's age_email: User's email address
Requirements:
- User must not be already registered
function updateProfile(string memory _name, uint256 _userId, uint256 _age, string memory _email) publicUpdates an existing user profile.
Parameters:
- Same as registerUser()
Requirements:
- User must be registered
function getProfile(address _user) external view returns (uint256, string memory, string memory, uint256, uint256)Retrieves complete profile information for a given address.
Returns:
- User ID, name, email, age, registration timestamp
function fetchUserInfo(address _user) external view returns (string memory, string memory, uint256, uint256)Alternative getter function for basic profile information.
Returns:
- Name, email, age, user ID
function isUserRegistered(address _user) external view returns (bool)Checks if a user is registered.
function getUserCount() external view returns (uint256)Returns total number of registered users (placeholder implementation).
event UserRegistered(address indexed user, string name, uint256 timestamp)Emitted when a new user registers.
event UserUpdated(address indexed user, string name)Emitted when a user updates their profile.
- Remix IDE or local development environment
- MetaMask or similar Ethereum wallet
- Test ETH for deployment (Sepolia, Goerli, or local testnet)
-
Using Remix:
- Open Remix IDE
- Create a new file
UserProfileRegistry.sol - Paste the contract code
- Compile with Solidity ^0.8.17
- Deploy using Injected Provider (MetaMask)
-
Using Hardhat/Truffle:
# Install dependencies npm install # Compile contracts npx hardhat compile # Deploy to testnet npx hardhat run scripts/deploy.js --network sepolia
// Register a new user
await contract.methods.registerUser(
"John Doe",
12345,
25,
"john@example.com"
).send({ from: userAddress });
// Update profile
await contract.methods.updateProfile(
"John Smith",
12345,
26,
"johnsmith@example.com"
).send({ from: userAddress });
// Get profile data
const profile = await contract.methods.getProfile(userAddress).call();
console.log(profile);// Import and use in another contract
import "./UserProfileRegistry.sol";
contract MyDApp {
UserProfileRegistry registry;
constructor(address _registryAddress) {
registry = UserProfileRegistry(_registryAddress);
}
function checkUser(address _user) public view returns (bool) {
return registry.isUserRegistered(_user);
}
}- Access Control: Users can only update their own profiles
- Input Validation: Consider adding validation for email format and name length
- Reentrancy: Current functions are safe from reentrancy attacks
- Gas Optimization: Profile updates could be optimized to only change specific fields
- Add input validation (email format, name length limits)
- Implement profile deletion functionality
- Add admin controls for emergency situations
- Consider using OpenZeppelin's security patterns
Test the contract thoroughly before mainnet deployment:
// Test registration
it("should register a new user", async () => {
await registry.registerUser("Test User", 1, 25, "test@example.com");
const isRegistered = await registry.isUserRegistered(accounts[0]);
assert.equal(isRegistered, true);
});
// Test duplicate registration prevention
it("should prevent duplicate registration", async () => {
await registry.registerUser("Test User", 1, 25, "test@example.com");
await expectRevert(
registry.registerUser("Test User 2", 2, 30, "test2@example.com"),
"User already registered"
);
});This project is licensed under the MIT License - see the LICENSE file for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
If you have questions or need help:
- Open an issue on GitHub
- Check the Solidity documentation
- Visit Ethereum Stack Exchange