evire
  • ⚪EVIRE
  • INTRODUCTION
    • ▪️Key Features and Capabilities
    • ▪️High-Level Architecture
    • ▪️Roadmap
    • ▪️Finances
    • ▪️Licensing
    • ▪️Tokenomics
      • EVIRE ERC20 token
      • Token Vesting
    • ▪️Audit
  • Core Concepts
    • ▪️Blockchain Basics
    • ▪️Ethereum Virtual Machine (EVM)
    • ▪️Smart Contracts and Decentralized Applications
  • TESTNET
    • Adding Evire Testnet to Metamask
    • Using the Evire Faucet
  • FRAMEWORKS AND NATIVE FUNCTIONS
    • ▪️Overview
  • AI Framework
    • ▪️Smart Contract Libraries for AI
      • Example: Data Preprocessing Libraries
      • Example: Model Execution and Management Library
    • ▪️Off-Chain Compute Framework
      • Example: AI-Powered Predictive Analytics dApp
      • Example: Off-Chain Computation Request Handling
    • ▪️Decentralized Storage Integration
      • Example: Data Linking via Smart Contracts
      • Example: On-Demand Data Retrieval Implementation
    • ▪️Oracles for Real-Time Data
      • Example: Real-Time Data Fetching Oracle for Financial Models
    • ▪️Model Training and Deployment Tools
      • Example: AI Model Deployment
    • ▪️AI-Specific Governance Protocols
      • Example: AI Governance Smart Contract for Bias Audit and Consensus Decision
    • ▪️User-Friendly Developer Interfaces
    • ▪️Privacy Tools and Standards
  • Gaming Framework
    • ▪️Specialized Gaming Smart Contract Libraries
      • Example: Secure and Fair Random Number Generation Library
      • Example: Asset Trading Library
      • Example: Game State Management Library
      • Example: Evire Player Stats Library
    • ▪️Scalable and Efficient Consensus Mechanisms
    • ▪️Interoperability Features
    • ▪️Robust Developer Tooling
    • ▪️User-Friendly SDKs and APIs
    • ▪️Regulatory Compliance Tools
    • ▪️Flexible Asset Management
  • RWA Framework
    • ▪️Identity Verification and Management Libraries
      • Example: Identity Verification Library
    • ▪️Oracles and Data Feeds
    • ▪️Asset Tokenization Frameworks
      • Example: Real Estate Tokenization Library
    • ▪️Legal Compliance and Smart Contract Auditing Tools
    • ▪️Interoperability Solutions
    • ▪️Privacy Enhancements
    • ▪️DeFi Integration Tools
    • ▪️User-Friendly Interfaces and SDKs
    • ▪️Governance Frameworks
    • ▪️Customizable Smart Contract Templates
  • DePIN Framework
    • ▪️Smart Contract Libraries
      • Example: Physical Infrastructure Management Library
    • ▪️Oracles Integration
    • ▪️IoT Integration Framework
    • ▪️Interoperability Protocols
    • ▪️Developer Tooling
    • ▪️User Interface Components
    • ▪️Security Auditing Tools
    • ▪️Governance and Compliance Frameworks
      • Example: Governance And Compliance Library
    • ▪️Tokenization Support
    • ▪️Documentation and Community Support
  • EXAMPLES
    • ▪️AI Framework
    • ▪️Gaming Framework
    • ▪️RWA Framework
    • ▪️DePIN Framework
  • Legal
    • ▪️Terms and Conditions of Participation
  • More
    • ▪️Faucet
    • ▪️Partners
    • ▪️Contribute
  • Links
    • ▪️Website
    • ▪️Twitter
    • ▪️Telegram
    • ▪️GitHub
    • ▪️Medium
    • ▪️Linktree
    • ◾DeBank
Powered by GitBook
On this page
  1. RWA Framework
  2. Asset Tokenization Frameworks

Example: Real Estate Tokenization Library

To illustrate how Evire's Asset Tokenization libraries can be utilized in a smart contract, we'll provide an example library that facilitates the tokenization of real-world assets. This example will focus on a basic implementation for tokenizing real estate assets.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract RealEstateToken is ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    struct Property {
        uint256 id;
        string location;
        uint256 valuation;
        bool forSale;
    }

    mapping(uint256 => Property) public properties;

    event PropertyTokenized(uint256 tokenId, string location, uint256 valuation, address owner);
    event PropertyForSale(uint256 tokenId, uint256 valuation);
    event PropertySold(uint256 tokenId, address newOwner, uint256 salePrice);

    constructor() ERC721("RealEstateToken", "RET") {}

    function tokenizeProperty(string memory _location, uint256 _valuation) public onlyOwner returns (uint256) {
        _tokenIds.increment();
        uint256 newPropertyId = _tokenIds.current();

        _mint(msg.sender, newPropertyId);
        _setTokenURI(newPropertyId, _location);

        properties[newPropertyId] = Property({
            id: newPropertyId,
            location: _location,
            valuation: _valuation,
            forSale: false
        });

        emit PropertyTokenized(newPropertyId, _location, _valuation, msg.sender);
        return newPropertyId;
    }

    function setForSale(uint256 _tokenId, uint256 _valuation) public onlyOwnerOf(_tokenId) {
        Property storage property = properties[_tokenId];
        property.forSale = true;
        property.valuation = _valuation;

        emit PropertyForSale(_tokenId, _valuation);
    }

    function buyProperty(uint256 _tokenId) public payable {
        Property storage property = properties[_tokenId];
        require(property.forSale, "Property not for sale");
        require(msg.value >= property.valuation, "Insufficient funds");

        address previousOwner = ownerOf(_tokenId);
        _transfer(previousOwner, msg.sender, _tokenId);

        property.forSale = false;

        payable(previousOwner).transfer(msg.value);

        emit PropertySold(_tokenId, msg.sender, msg.value);
    }

    modifier onlyOwnerOf(uint256 _tokenId) {
        require(ownerOf(_tokenId) == msg.sender, "Not the owner");
        _;
    }
}

Explanation

  • We use OpenZeppelin's ERC721 standard to represent the real estate as non-fungible tokens (NFTs). The Ownable contract ensures that only the contract owner can perform certain actions.

  • This struct holds details about each property, including its unique ID, location, valuation, and sale status.

  • The tokenizeProperty function allows the owner to create a new property token. This function mints a new ERC721 token, sets its metadata (location), and stores the property details.

  • The setForSale function allows the owner to mark a property as available for sale and set its valuation.

  • The buyProperty function allows someone to purchase a property that is for sale by sending the appropriate amount of Ether. The ownership of the token is transferred, and the previous owner is paid.

Example of Usage:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./RWAFW/RealEstateToken.sol";

contract ExtendedRealEstateToken is RealEstateToken {
    struct CoOwner {
        address owner;
        uint256 share; // Percentage of ownership
    }

    mapping(uint256 => CoOwner[]) public coOwners;
    mapping(uint256 => uint256) public rentalIncome;
    mapping(uint256 => mapping(address => uint256)) public withdrawnDividends;

    event DividendWithdrawn(uint256 tokenId, address coOwner, uint256 amount);
    event BidPlaced(uint256 tokenId, address bidder, uint256 bidAmount);
    event BidAccepted(uint256 tokenId, address previousOwner, address newOwner, uint256 bidAmount);

    function addCoOwner(uint256 _tokenId, address _coOwner, uint256 _share) public onlyOwnerOf(_tokenId) {
        coOwners[_tokenId].push(CoOwner({
            owner: _coOwner,
            share: _share
        }));
    }

    function distributeRentalIncome(uint256 _tokenId, uint256 _amount) public onlyOwnerOf(_tokenId) {
        rentalIncome[_tokenId] += _amount;
    }

    function withdrawDividend(uint256 _tokenId) public {
        uint256 totalIncome = rentalIncome[_tokenId];
        require(totalIncome > 0, "No income to withdraw");

        uint256 ownerShare;
        for (uint256 i = 0; i < coOwners[_tokenId].length; i++) {
            if (coOwners[_tokenId][i].owner == msg.sender) {
                ownerShare = coOwners[_tokenId][i].share;
                break;
            }
        }

        uint256 withdrawableAmount = (totalIncome * ownerShare / 100) - withdrawnDividends[_tokenId][msg.sender];
        require(withdrawableAmount > 0, "No dividends to withdraw");

        withdrawnDividends[_tokenId][msg.sender] += withdrawableAmount;
        payable(msg.sender).transfer(withdrawableAmount);

        emit DividendWithdrawn(_tokenId, msg.sender, withdrawableAmount);
    }

    function placeBid(uint256 _tokenId) public payable {
        require(properties[_tokenId].forSale, "Property not for sale");
        require(msg.value > properties[_tokenId].valuation, "Bid is too low");

        emit BidPlaced(_tokenId, msg.sender, msg.value);
    }

    function acceptBid(uint256 _tokenId, address _bidder, uint256 _bidAmount) public onlyOwnerOf(_tokenId) {
        require(properties[_tokenId].forSale, "Property not for sale");
        require(_bidAmount > properties[_tokenId].valuation, "Bid amount is too low");

        address previousOwner = ownerOf(_tokenId);
        _transfer(previousOwner, _bidder, _tokenId);

        properties[_tokenId].forSale = false;

        payable(previousOwner).transfer(_bidAmount);

        emit BidAccepted(_tokenId, previousOwner, _bidder, _bidAmount);
    }

    function getCoOwners(uint256 _tokenId) public view returns (CoOwner[] memory) {
        return coOwners[_tokenId];
    }
}

Explanation

  • The CoOwner struct allows multiple addresses to own a share of the property. The addCoOwner function assigns shares to different co-owners.

  • The contract manages rental income distribution through distributeRentalIncome and allows co-owners to withdraw their share of the rental income using withdrawDividend.

  • The contract supports a bidding mechanism where potential buyers can place bids on properties that are for sale, and owners can accept these bids through placeBid and acceptBid.

  • Events like DividendWithdrawn, BidPlaced, and BidAccepted provide a way to track important actions within the contract.

This example demonstrates how to build a real estate management system using Solidity and the RealEstateToken.sol library. It covers tokenization, co-ownership, rental income distribution and a bidding system, showcasing the versatility and power of Solidity for creating advanced blockchain applications.

PreviousAsset Tokenization FrameworksNextLegal Compliance and Smart Contract Auditing Tools

Last updated 11 months ago

▪️