# Your first project

This guide shows how to create a simple Solidity project that interacts with Hortifuel DAO contracts.

{% hint style="info" %}
Start with read-only contract calls first. They are the fastest way to learn the protocol surface safely.
{% endhint %}

## What you'll learn

By the end of this guide, you will understand how to:

* connect to a deployed Hortifuel contract
* import or define an interface
* read on-chain data
* call protocol methods from your own smart contract
* understand when authorization is required

## What you will build

In this example, you will build a small Solidity contract that reads asset data from `RWARegistry`.

This is a good first project because it teaches the core pattern used throughout the Hortifuel ecosystem:

1. define an interface
2. store the target contract address
3. call public methods on the target contract
4. return or use the results in your own application logic

## Prerequisites

Before you begin, make sure you have:

* a Solidity development environment
* the deployed address of `RWARegistry`
* access to the contract ABI or interface
* a wallet and RPC provider if you also want to test transactions

## Step 1: Define the interface

Your contract needs an interface for the methods it wants to call.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IRWARegistry {
    enum AssetType {
        RealEstate,
        Land,
        Equipment,
        Facility,
        InventoryLot,
        ProductBatch,
        WarehouseLot,
        Shipment,
        Certificate,
        License,
        IntellectualProperty,
        CommodityLot,
        TreasuryAsset,
        Other
    }

    enum AssetStatus {
        Draft,
        Active,
        Verified,
        Locked,
        Redeemed,
        Retired
    }

    enum VerificationStatus {
        Unverified,
        Pending,
        Verified,
        Rejected
    }

    struct AssetRecord {
        string assetCode;
        string name;
        string description;
        string location;
        string metadataURI;
        string jurisdiction;
        AssetType assetType;
        AssetStatus status;
        VerificationStatus verificationStatus;
        uint256 linkedTokenId;
        address custodian;
        bool tokenized;
        bool active;
        bool frozen;
        uint256 createdAt;
        uint256 updatedAt;
    }

    function getAsset(uint256 assetId) external view returns (AssetRecord memory);
}
```

### Why this matters

Your interface must match the deployed contract exactly. A wrong signature will break the call.

## Step 2: Create your project contract

Now create a contract that stores the registry address and reads asset data.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IRWARegistry {
    enum AssetType {
        RealEstate,
        Land,
        Equipment,
        Facility,
        InventoryLot,
        ProductBatch,
        WarehouseLot,
        Shipment,
        Certificate,
        License,
        IntellectualProperty,
        CommodityLot,
        TreasuryAsset,
        Other
    }

    enum AssetStatus {
        Draft,
        Active,
        Verified,
        Locked,
        Redeemed,
        Retired
    }

    enum VerificationStatus {
        Unverified,
        Pending,
        Verified,
        Rejected
    }

    struct AssetRecord {
        string assetCode;
        string name;
        string description;
        string location;
        string metadataURI;
        string jurisdiction;
        AssetType assetType;
        AssetStatus status;
        VerificationStatus verificationStatus;
        uint256 linkedTokenId;
        address custodian;
        bool tokenized;
        bool active;
        bool frozen;
        uint256 createdAt;
        uint256 updatedAt;
    }

    function getAsset(uint256 assetId) external view returns (AssetRecord memory);
}

contract MyFirstHortifuelProject {
    IRWARegistry public registry;

    constructor(address registryAddress) {
        registry = IRWARegistry(registryAddress);
    }

    function getAssetName(uint256 assetId) external view returns (string memory) {
        IRWARegistry.AssetRecord memory asset = registry.getAsset(assetId);
        return asset.name;
    }

    function getAssetStatus(uint256 assetId) external view returns (IRWARegistry.AssetStatus) {
        IRWARegistry.AssetRecord memory asset = registry.getAsset(assetId);
        return asset.status;
    }

    function isAssetActive(uint256 assetId) external view returns (bool) {
        IRWARegistry.AssetRecord memory asset = registry.getAsset(assetId);
        return asset.active;
    }
}
```

## Step 3: Deploy with the registry address

When you deploy your contract, pass in the deployed `RWARegistry` address.

That connects your project contract to the live Hortifuel DAO registry.

## Step 4: Call read methods

After deployment, you can call:

* `getAssetName(assetId)`
* `getAssetStatus(assetId)`
* `isAssetActive(assetId)`

These methods read protocol state without changing blockchain state.

## Step 5: Understand public reads vs restricted writes

This first project uses public read methods. That is the easiest way to start.

Many Hortifuel DAO write methods are restricted. Examples include:

* asset registration
* valuation updates
* verification updates
* product registration
* compliance updates

{% hint style="warning" %}
If your own contract calls a restricted method, the target contract checks your contract address as `msg.sender`.
{% endhint %}

## Important permission rule

Your wallet being authorized is not always enough.

Your contract may also need explicit authorization before it can call privileged protocol methods.

## Example expansion ideas

After completing this first project, you can expand it to:

* read product data from `HemiVault`
* read balances from `HFUELToken`
* read metadata from `Hunits`
* submit redemption requests to `HortiRedeem`
* integrate governance participation flows

## Common mistakes

#### Forgetting the correct contract address

Always confirm you are using the deployed address for the current network.

#### Calling restricted methods without authorization

Many write methods will revert unless the caller has the right role.

#### Using the wrong interface

Your Solidity interface must match the deployed contract's method signatures exactly.

#### Ignoring reverts for missing records

Calls for non-existent asset IDs may revert.

## Next steps

Continue with:

* [Quickstart](/documentation/getting-started/quickstart.md)
* [Reference](/documentation/reference/coming-soon.md)
* [Configuration](broken://spaces/zeYz4SvPbzIzqDqWUurf/pages/65332f63d0b6cedd6ac718136ba8d89ec6cc1a4d)

## Summary

Your first Hortifuel DAO project should focus on reading from an existing protocol contract through a Solidity interface.

Once that flow works, move on to role-aware write methods and contract-specific integrations.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hortifuel.com/documentation/getting-started/your-first-project.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
