├── test └── test.js ├── .gitignore ├── migrations └── 1_deploy.js ├── package.json ├── README.md ├── truffle-config.js └── contracts └── LandContract.sol /test/test.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | package-lock.json 4 | build -------------------------------------------------------------------------------- /migrations/1_deploy.js: -------------------------------------------------------------------------------- 1 | // migrations/1_deploy.js 2 | const LandContract = artifacts.require('LandContract'); 3 | 4 | module.exports = async function (deployer) { 5 | await deployer.deploy(LandContract); 6 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blockchain-based-land-registry-system", 3 | "version": "1.0.0", 4 | "description": "This is my first real world project on blockchain", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/MirzaMuhammadBaig/Blockchain-based-Land-Registry-System.git" 12 | }, 13 | "keywords": [ 14 | "Awesome" 15 | ], 16 | "author": "MirzaMuhammadBaig", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/MirzaMuhammadBaig/Blockchain-based-Land-Registry-System/issues" 20 | }, 21 | "homepage": "https://github.com/MirzaMuhammadBaig/Blockchain-based-Land-Registry-System#readme", 22 | "devDependencies": { 23 | "truffle": "^5.7.3" 24 | }, 25 | "dependencies": { 26 | "dotenv": "^16.0.3", 27 | "web3": "^1.8.1", 28 | "@truffle/hdwallet-provider": "^2.0.13" 29 | } 30 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project About Remove Frauda And Difficulties during sell and buy property. 2 | 3 | This project is a basic land registration smart contract on the Ethereum blockchain. It allows users to register, verify, and reject sellers, buyers, and land registration. The project is written in Solidity, and the contract has been tested using the Solidity compiler version 0.8.17. 4 | 5 | ### How to Use 6 | #### Contract Deployment 7 | To deploy the contract, you will need to have access to an Ethereum blockchain network, such as a local development network or a test network like goerli. You can deploy the contract using Remix or any other Solidity IDE of your choice. 8 | 9 | #### Contract Interactions 10 | Once the contract is deployed, you can interact with it using a Web3-enabled browser or a Web3 library like Web3.js. The following functions are available for interaction with the contract: 11 | 12 | - RegisterSeller: Allows a seller to register with their details. 13 | 14 | - VerifySeller: Allows the Land Inspector to verify a seller. 15 | 16 | - RejectSeller: Allows the Land Inspector to reject a seller. 17 | 18 | - RegisterBuyer: Allows a buyer to register with their details. 19 | 20 | - VerifyBuyer: Allows the Land Inspector to verify a buyer. 21 | 22 | - RejectBuyer: Allows the Land Inspector to reject a buyer. 23 | 24 | - RegisterLand: Allows a user to register land with the specified details. 25 | 26 | - VerifyLand: Allows the Land Inspector to verify a land registration. 27 | 28 | - RejectLand: Allows the Land Inspector to reject a land registration. 29 | 30 | - UpdateSeller: Allows a seller to update their details. 31 | 32 | - UpdateBuyer: Allows a buyer to update their details. 33 | 34 | - GetLandDetails: Returns the details of a land registration by LandID. 35 | 36 | - GetLandOwner: Returns the owner of the land registration by LandID. 37 | 38 | - GetLandCity: Returns the city of the land registration by LandID. 39 | 40 | - GetLandPrice: Returns the price of the land registration by LandID. 41 | 42 | - GetLandArea: Returns the area of the land registration by LandID. 43 | 44 | #### Smart Contract Security 45 | - The smart contract has been written with security in mind, and the following measures have been taken to prevent potential vulnerabilities: 46 | 47 | - The contract uses the onlylandinspector modifier to ensure that only the Land Inspector can perform certain functions. 48 | 49 | - The contract uses mappings to store the details of buyers, sellers, and land registrations. 50 | 51 | - The contract uses the require statement to ensure that only verified sellers, buyers, and land registrations can interact with the contract. 52 | 53 | #### License 54 | - This project is licensed under the MIT License. 55 | 56 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file to configure your truffle project. It's seeded with some 3 | * common settings for different networks and features like migrations, 4 | * compilation, and testing. Uncomment the ones you need or modify 5 | * them to suit your project as necessary. 6 | * 7 | * More information about configuration can be found at: 8 | * 9 | * https://trufflesuite.com/docs/truffle/reference/configuration 10 | * 11 | * Hands-off deployment with Infura 12 | * -------------------------------- 13 | * 14 | * Do you have a complex application that requires lots of transactions to deploy? 15 | * Use this approach to make deployment a breeze 🏖️: 16 | * 17 | * Infura deployment needs a wallet provider (like @truffle/hdwallet-provider) 18 | * to sign transactions before they're sent to a remote public node. 19 | * Infura accounts are available for free at 🔍: https://infura.io/register 20 | * 21 | * You'll need a mnemonic - the twelve word phrase the wallet uses to generate 22 | * public/private key pairs. You can store your secrets 🤐 in a .env file. 23 | * In your project root, run `$ npm install dotenv`. 24 | * Create .env (which should be .gitignored) and declare your MNEMONIC 25 | * and Infura PROJECT_ID variables inside. 26 | * For example, your .env file will have the following structure: 27 | * 28 | * MNEMONIC = 29 | * PROJECT_ID = 30 | * 31 | * Deployment with Truffle Dashboard (Recommended for best security practice) 32 | * -------------------------------------------------------------------------- 33 | * 34 | * Are you concerned about security and minimizing rekt status 🤔? 35 | * Use this method for best security: 36 | * 37 | * Truffle Dashboard lets you review transactions in detail, and leverages 38 | * MetaMask for signing, so there's no need to copy-paste your mnemonic. 39 | * More details can be found at 🔎: 40 | * 41 | * https://trufflesuite.com/docs/truffle/getting-started/using-the-truffle-dashboard/ 42 | */ 43 | 44 | require('dotenv').config(); 45 | const { MNEMONIC, PROJECT_ID } = process.env; 46 | 47 | const HDWalletProvider = require('@truffle/hdwallet-provider'); 48 | 49 | module.exports = { 50 | /** 51 | * Networks define how you connect to your ethereum client and let you set the 52 | * defaults web3 uses to send transactions. If you don't specify one truffle 53 | * will spin up a managed Ganache instance for you on port 9545 when you 54 | * run `develop` or `test`. You can ask a truffle command to use a specific 55 | * network from the command line, e.g 56 | * 57 | * $ truffle test --network 58 | */ 59 | 60 | networks: { 61 | // Useful for testing. The `development` name is special - truffle uses it by default 62 | // if it's defined here and no other network is specified at the command line. 63 | // You should run a client (like ganache, geth, or parity) in a separate terminal 64 | // tab if you use this network and you must also set the `host`, `port` and `network_id` 65 | // options below to some value. 66 | // 67 | // development: { 68 | // host: "127.0.0.1", // Localhost (default: none) 69 | // port: 8545, // Standard Ethereum port (default: none) 70 | // network_id: "*", // Any network (default: none) 71 | // }, 72 | // 73 | // An additional network, but with some advanced options… 74 | // advanced: { 75 | // port: 8777, // Custom port 76 | // network_id: 1342, // Custom network 77 | // gas: 8500000, // Gas sent with each transaction (default: ~6700000) 78 | // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) 79 | // from:
, // Account to send transactions from (default: accounts[0]) 80 | // websocket: true // Enable EventEmitter interface for web3 (default: false) 81 | // }, 82 | // 83 | // Useful for deploying to a public network. 84 | // Note: It's important to wrap the provider as a function to ensure truffle uses a new provider every time. 85 | goerli: { 86 | provider: () => new HDWalletProvider(MNEMONIC, `https://goerli.infura.io/v3/${PROJECT_ID}`), 87 | network_id: 5, // Goerli's id 88 | confirmations: 2, // # of confirmations to wait between deployments. (default: 0) 89 | timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) 90 | skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) 91 | }, 92 | // 93 | // Useful for private networks 94 | // private: { 95 | // provider: () => new HDWalletProvider(MNEMONIC, `https://network.io`), 96 | // network_id: 2111, // This network is yours, in the cloud. 97 | // production: true // Treats this network as if it was a public net. (default: false) 98 | // } 99 | }, 100 | 101 | // Set default mocha options here, use special reporters, etc. 102 | mocha: { 103 | // timeout: 100000 104 | }, 105 | 106 | // Configure your compilers 107 | compilers: { 108 | solc: { 109 | version: "0.8.17" // Fetch exact version from solc-bin (default: truffle's version) 110 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) 111 | // settings: { // See the solidity docs for advice about optimization and evmVersion 112 | // optimizer: { 113 | // enabled: false, 114 | // runs: 200 115 | // }, 116 | // evmVersion: "byzantium" 117 | // } 118 | } 119 | } 120 | 121 | // Truffle DB is currently disabled by default; to enable it, change enabled: 122 | // false to enabled: true. The default storage location can also be 123 | // overridden by specifying the adapter settings, as shown in the commented code below. 124 | // 125 | // NOTE: It is not possible to migrate your contracts to truffle DB and you should 126 | // make a backup of your artifacts to a safe location before enabling this feature. 127 | // 128 | // After you backed up your artifacts you can utilize db by running migrate as follows: 129 | // $ truffle migrate --reset --compile-all 130 | // 131 | // db: { 132 | // enabled: false, 133 | // host: "127.0.0.1", 134 | // adapter: { 135 | // name: "indexeddb", 136 | // settings: { 137 | // directory: ".db" 138 | // } 139 | // } 140 | // } 141 | }; 142 | -------------------------------------------------------------------------------- /contracts/LandContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.17; 3 | 4 | contract LandRegistration { 5 | struct RegistrationLand { 6 | string Area; 7 | string City; 8 | string State; 9 | uint LandPriceInWei; 10 | uint PropertyPID; 11 | address Owner; 12 | } 13 | 14 | struct BuyerDetail { 15 | string Name; 16 | uint Age; 17 | string City; 18 | string CNIC; 19 | string Email; 20 | } 21 | 22 | struct SellerDetail { 23 | string Name; 24 | uint Age; 25 | string City; 26 | string CNIC; 27 | string Email; 28 | } 29 | 30 | struct LandInspectorDetail { 31 | address ID; 32 | string Name; 33 | uint Age; 34 | string Designation; 35 | } 36 | 37 | //mappings 38 | 39 | mapping(uint => RegistrationLand) public LandDetails; 40 | mapping(address => BuyerDetail) public BuyerDetails; 41 | mapping(address => SellerDetail) public SellerDetails; 42 | mapping(address => LandInspectorDetail) public LandInspectorDetails; 43 | mapping(address => bool) public IsBuyerVerify; 44 | mapping(address => bool) public IsSellerVerify; 45 | mapping(uint => bool) public IsLandVerify; 46 | 47 | address public LandInspector; 48 | 49 | constructor() payable { 50 | LandInspector = msg.sender; 51 | } 52 | 53 | modifier onlylandinspector() { 54 | require(msg.sender == LandInspector, "you are not land inspector"); 55 | _; 56 | } 57 | 58 | // function of register seller 59 | 60 | function RegisterSeller( 61 | address, 62 | string memory NAME, 63 | uint AGE, 64 | string memory CITY, 65 | string memory CNIC, 66 | string memory Email 67 | ) public { 68 | SellerDetails[msg.sender] = SellerDetail(NAME, AGE, CITY, CNIC, Email); 69 | 70 | require(IsSellerVerify[msg.sender] == true, "please verify seller"); 71 | } 72 | 73 | //function of verify seller 74 | 75 | function VerifySeller(address add) public onlylandinspector { 76 | IsSellerVerify[add] = true; 77 | } 78 | 79 | //function of reject seller 80 | 81 | function RejectSeller(address add) public onlylandinspector { 82 | IsSellerVerify[add] = false; 83 | } 84 | 85 | //function of register buyer 86 | 87 | function RegisterBuyer( 88 | address addr, 89 | string memory NAME, 90 | uint AGE, 91 | string memory CITY, 92 | string memory CNIC, 93 | string memory Email 94 | ) public { 95 | BuyerDetails[addr] = BuyerDetail(NAME, AGE, CITY, CNIC, Email); 96 | 97 | require(IsBuyerVerify[msg.sender] == true, "please verify buyer"); 98 | } 99 | 100 | //function of verify buyer 101 | 102 | function VerifyBuyer(address addr) public onlylandinspector { 103 | IsBuyerVerify[addr] = true; 104 | } 105 | 106 | //function of reject buyer 107 | 108 | function RejectBuyer(address addr) public onlylandinspector { 109 | IsBuyerVerify[addr] = false; 110 | } 111 | 112 | //function of land registration 113 | 114 | function RegisterLand( 115 | uint _LandID, 116 | string memory Area, 117 | string memory City, 118 | string memory State, 119 | uint LandPriceInWei, 120 | uint PropertyPID, 121 | address 122 | ) public { 123 | LandDetails[_LandID] = RegistrationLand( 124 | Area, 125 | City, 126 | State, 127 | LandPriceInWei, 128 | PropertyPID, 129 | msg.sender 130 | ); 131 | 132 | require(IsLandVerify[_LandID] == true, "please verify Land"); 133 | } 134 | 135 | //function of land verify 136 | 137 | function VerifyLand(uint _LandID) public onlylandinspector { 138 | IsLandVerify[_LandID] = true; 139 | } 140 | 141 | //function of reject land 142 | 143 | function RejectLand(uint _LandID) public onlylandinspector { 144 | IsLandVerify[_LandID] = false; 145 | } 146 | 147 | // seller update 148 | 149 | function UpdateSeller( 150 | address addr, 151 | string memory Name_, 152 | uint Age_, 153 | string memory City_, 154 | string memory CNIC_, 155 | string memory Email_ 156 | ) public { 157 | SellerDetails[addr].Name = Name_; 158 | SellerDetails[addr].Age = Age_; 159 | SellerDetails[addr].City = City_; 160 | SellerDetails[addr].CNIC = CNIC_; 161 | SellerDetails[addr].Email = Email_; 162 | } 163 | 164 | // buyer update 165 | 166 | function UpdateBuyer( 167 | address addr, 168 | string memory Name_, 169 | uint Age_, 170 | string memory City_, 171 | string memory CNIC_, 172 | string memory Email_ 173 | ) public { 174 | BuyerDetails[addr].Name = Name_; 175 | BuyerDetails[addr].Age = Age_; 176 | BuyerDetails[addr].City = City_; 177 | BuyerDetails[addr].CNIC = CNIC_; 178 | BuyerDetails[addr].Email = Email_; 179 | } 180 | 181 | // get land details by landID 182 | 183 | function GetLandDetails( 184 | uint ID 185 | ) 186 | public 187 | view 188 | returns (string memory, string memory, string memory, uint, uint) 189 | { 190 | return ( 191 | LandDetails[ID].Area, 192 | LandDetails[ID].City, 193 | LandDetails[ID].State, 194 | LandDetails[ID].LandPriceInWei, 195 | LandDetails[ID].PropertyPID 196 | ); 197 | } 198 | 199 | // check owner by landID 200 | 201 | function GetLandOwner(uint _LandID) public view returns (address) { 202 | return LandDetails[_LandID].Owner; 203 | } 204 | 205 | // get city by landID 206 | 207 | function GetLandCity(uint ID) public view returns (string memory) { 208 | return (LandDetails[ID].City); 209 | } 210 | 211 | // get land price by landID 212 | 213 | function GetLandPrice(uint ID) public view returns (uint) { 214 | return (LandDetails[ID].LandPriceInWei); 215 | } 216 | 217 | // get area by landID 218 | 219 | function GetLandArea(uint ID) public view returns (string memory) { 220 | return (LandDetails[ID].Area); 221 | } 222 | 223 | // function of register land inspector 224 | 225 | function RegisterLandInspector( 226 | address ID, 227 | string memory NAME, 228 | uint AGE, 229 | string memory Designation 230 | ) public { 231 | LandInspectorDetails[LandInspector] = LandInspectorDetail( 232 | ID, 233 | NAME, 234 | AGE, 235 | Designation 236 | ); 237 | } 238 | 239 | // buy land 240 | 241 | function BuyLand(uint _LandID) public payable { 242 | require(IsBuyerVerify[msg.sender] == true, "please verify buyer"); 243 | require(IsLandVerify[_LandID] == true, "please verify land"); 244 | payable(LandDetails[_LandID].Owner).transfer(msg.value); 245 | require( 246 | msg.value >= LandDetails[_LandID].LandPriceInWei, 247 | "please pay me ether" 248 | ); 249 | LandDetails[_LandID].Owner = msg.sender; 250 | } 251 | 252 | //transfer land 253 | 254 | function TransferLandOwnerShip(uint _LandID, address newOwner) public { 255 | LandDetails[_LandID].Owner = newOwner; 256 | } 257 | } 258 | --------------------------------------------------------------------------------