What it does:
Records, verifies, and transfers land ownership on-chain, ensuring that property records are immutable, transparent, and tamper-proof.
Why it matters:
Eliminates fraud, duplicate titles, and opaque paperwork by creating a single source of truth for land ownership that anyone can verify but no one can secretly alter.
How it works:
Land parcels are registered with unique IDs and metadata at deployment or by an authorized registrar.
Each land parcel is linked to a single owner address on-chain.
Ownership transfers require the current owner’s consent and are permanently recorded.
Historical ownership remains publicly auditable, creating trust and legal clarity.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title LandRegistry
* @author Nam
* @notice Decentralized land ownership registry on blockchain
*/
contract LandRegistry {
// -------------------- ROLES --------------------
address public registrar; // government / authority / trusted entity
// -------------------- LAND STRUCT --------------------
struct Land {
uint256 landId;
address owner;
string metadata; // IPFS hash / land description
bool exists;
}
// -------------------- STORAGE --------------------
mapping(uint256 => Land) public lands;
// -------------------- EVENTS --------------------
event LandRegistered(uint256 indexed landId, address indexed owner);
event OwnershipTransferred(
uint256 indexed landId,
address indexed from,
address indexed to
);
// -------------------- MODIFIERS --------------------
modifier onlyRegistrar() {
require(msg.sender == registrar, "Not registrar");
_;
}
modifier landExists(uint256 _landId) {
require(lands[_landId].exists, "Land not registered");
_;
}
modifier onlyOwner(uint256 _landId) {
require(msg.sender == lands[_landId].owner, "Not land owner");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor() {
registrar = msg.sender;
}
// -------------------- REGISTRATION LOGIC --------------------
/**
* @notice Register a new land parcel
* @param _landId Unique land identifier
* @param _owner Initial owner address
* @param _metadata Property details (IPFS hash / legal description)
*/
function registerLand(
uint256 _landId,
address _owner,
string calldata _metadata
) external onlyRegistrar {
require(!lands[_landId].exists, "Land already exists");
require(_owner != address(0), "Invalid owner");
lands[_landId] = Land({
landId: _landId,
owner: _owner,
metadata: _metadata,
exists: true
});
emit LandRegistered(_landId, _owner);
}
// -------------------- OWNERSHIP TRANSFER --------------------
/**
* @notice Transfer land ownership to a new owner
* @param _landId Land identifier
* @param _newOwner New owner address
*/
function transferOwnership(
uint256 _landId,
address _newOwner
)
external
landExists(_landId)
onlyOwner(_landId)
{
require(_newOwner != address(0), "Invalid new owner");
address previousOwner = lands[_landId].owner;
lands[_landId].owner = _newOwner;
emit OwnershipTransferred(_landId, previousOwner, _newOwner);
}
// -------------------- VIEW FUNCTIONS --------------------
/**
* @notice Get land details
*/
function getLand(uint256 _landId)
external
view
landExists(_landId)
returns (
uint256 landId,
address owner,
string memory metadata
)
{
Land memory land = lands[_landId];
return (land.landId, land.owner, land.metadata);
}
}
Build and Grow By Nam Le Thanh