Ethereum User Authentication
WEB3
In decentralized applications, unlike traditional web applications that rely on centralized databases and authentication, has its own challenges and opportunities. To this end, smart contract-based authentication serves as the backbone of managing user registration and login using Ethereum addresses as unique identifiers.
YouTube Tutorial
The video that goes through the below content in streaming format is as follows:
Below is the code for a basic authentication contract:
In the above code:
pragma solidity ^0.8.0; specifies the Solidity compiler version to use, ensuring compatibility
contract BasicAuth begins the declaration of a new contract called ‘BasicAuth’
struct User {string username; bool exists;} represents a user within a smart contract containing two fields:
username of the string data type that holds the username of the users
exists of the boolean data type that indicates whether a user has been registered in the contract
mapping(address => User) private users; declares a mapping named users, which is a key-value store for associating Ethereum addresses with User structs.
event UserRegistered(address userAddress, string username); emits an event containing the address and username of the user when a new user is registered in the system.
event UserLoggedIn(address userAddress); emits the ‘UserLoggedIn’ event, including the user’s address as an argument, when a user logs into the system.
function register(string calldata _username) external {
require(!users[msg.sender].exists, "User already exists");
users[msg.sender] = User({
username: _username,
exists: true
});
emit UserRegistered(msg.sender, _username); } onboards a new user to the contract, associating a unique Ethereum address (‘msg.sender’) with a ‘username’.
require(!users[msg.sender].exists, "User already exists"); checks if a user already exists as a registered user.
users[msg.sender] = User({username: _username, exists: true}); creates a new ‘User’ struct if the user does not already exist and assigns to the caller’s address in the ‘users’ mapping.
function login() external {
require(users[msg.sender].exists, "User does not exist");
emit UserLoggedIn(msg.sender); } declares a function named ‘login’ with ‘external’ visibility, so it can only be called from outside the contract.
‘require(users[msg.sender].exists, "User does not exist");’ checks if the caller of the function ‘msg.sender’ is registered as a user in the contract
If the check passes indicating the user does exist, ‘emit UserLoggedIn(msg.sender);’ emits the ‘UserLoggedIn’ event with ‘msg.sender’ as its parameter.
function getUsername() external view returns (string memory) {
require(users[msg.sender].exists, "User does not exist");
return users[msg.sender].username; } retrieves the username associated with the Ethereum address of the caller (‘msg.sender’).
‘require(users[msg.sender].exists, "User does not exist");’ checks is the user exists in the contract.
If the check passes indicating the user does exist, return users[msg.sender].username; returns the ‘username’ associated with the caller’s address.
I thought you might find this interesting.
CodeChat
February’s CodeChat will be held on Feb 23 at 5pm EST for anyone interested to have a discussion about Web3 development. You may sign up here for a meeting reminder or the meeting link is here if you would like to join directly.
As always, you can share any feedback you may have by replying to this email or leave a message in the Substacker’s message board.



