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:

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.

Last updated