Розробка мобільного додатку для DAO (голосування, пропозиції)

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Розробка мобільного додатку для DAO (голосування, пропозиції)
Складний
від 1 тижня до 3 місяців
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Розроблення мобільних додатків для DAO (голосування, пропозиції)

DAO-додаток — це інтерфейс до смарт-контракту управління. Власники токенів створюють пропозиції, голосують, делегують голоси, стежать за виконанням. На відміну від NFT або DeFi, UX тут орієнтований на читання: більшість користувачів голосує, а не створює пропозиції. Екран списку пропозицій — головна точка входу.

Стандарти: OpenZeppelin Governor vs. Snapshot

Два принципово різні підходи:

On-chain (Governor): все відбувається в блокчейні. OpenZeppelin Governor — стандарт де-факто. Голосування коштує газ, але результати криптографічно верифіковані. GovernorBravo, GovernorAlpha — форки використовують Compound, Uniswap, Aave.

Off-chain (Snapshot): підписи EIP-712 без транзакцій. Голосування безкоштовне, зберігається в мережі Snapshot. Результати не виконуються автоматично — потребує multisig або виконавця.

Більшість DAO комбінують обидва: Snapshot для голосування (без газу), Governor для виконання прийнятих пропозицій. Додаток має підтримувати обидва.

Список пропозицій: дані та стани

Пропозиція проходить через кілька станів:

Стан Governor Описання
Pending 0 Голосування ще не почалось
Active 1 Голосування відкрите
Canceled 2 Скасовано автором
Defeated 3 Не набрало кворум чи більшість
Succeeded 4 Пройшло, чекає запису в чергу
Queued 5 У TimeLock, чекає виконання
Expired 6 Дедлайн виконання істік
Executed 7 Виконано

Отримуйте дані через IGovernor.state(proposalId). Отримуйте список пропозицій через The Graph або Tally API. Прямі виклики контракту неефективні: немає нативного методу getProposals().

// iOS — отримання пропозицій через Tally GraphQL API
struct TallyProposalsQuery: Codable {
    // GraphQL запит для отримання пропозицій DAO
    static let query = """
    query Proposals($governorId: ID!, $first: Int!) {
      proposals(
        governorId: $governorId,
        pagination: { first: $first },
        sort: { sortBy: id, isDescending: true }
      ) {
        id
        title
        description
        status
        voteStats { support votes percent }
        start { ... on Block { timestamp } }
        end { ... on Block { timestamp } }
      }
    }
    """
}

Tally, Boardroom, Messari Governance — агрегатори з API для більшості крупних DAO. Для власних DAO — The Graph з субграфом OpenZeppelin Governor.

Екран пропозиції

Структура екрану:

  • Заголовок та описання (Markdown → відрендерений текст)
  • Статус та часові рамки (початок, конец, таймер)
  • Результати у реальному часі: For / Against / Abstain з відсотками та прогресс-барами
  • Кворум: набрано X з Y голосів (прогрес до порога)
  • Кнопки голосування (лише в статусі Active)
  • Історія подій: хто голосував, коли
// Android — відображення результатів голосування
data class ProposalVoteStats(
    val forVotes: BigDecimal,
    val againstVotes: BigDecimal,
    val abstainVotes: BigDecimal
) {
    val totalVotes get() = forVotes + againstVotes + abstainVotes
    val forPercent get() = if (totalVotes > BigDecimal.ZERO)
        (forVotes / totalVotes * BigDecimal(100)).toInt() else 0
    val quorumReached get() = totalVotes >= quorumThreshold
}

Голосування: On-chain та Off-chain (Snapshot)

On-chain: governor.castVote(proposalId, support) — три значення support: 0 (Against), 1 (For), 2 (Abstain). З причиною: castVoteWithReason(proposalId, support, reason). Транзакція коштує газ.

Snapshot off-chain: підпис повідомлення EIP-712, відправлено в Snapshot API:

// iOS — голосування через Snapshot API (без транзакції)
struct SnapshotVotePayload: Codable {
    let version: String      // "0.1.3"
    let timestamp: Int
    let space: String        // ID простору DAO
    let type: String         // "single-choice", "approval", "quadratic"
    let payload: VotePayload

    struct VotePayload: Codable {
        let proposal: String  // IPFS хеш пропозиції
        let choice: Int       // 1 = For, 2 = Against
        let metadata: String  // "{}"
    }
}

Підпишіть через WalletConnect або вбудований гаманець. Безкоштовне — головна перевага Snapshot.

Делегування голосів

Багато токенів підтримують делегування (ERC20Votes): власники можуть передати голосуючу силу іншій адресі без передачі токенів.

token.delegate(delegateeAddress) — одна транзакція. Доки не викликано — токени не беруть участь у голосуванні Governor, навіть якщо на балансі.

UX: при першому запуску DAO-додатку перевірте, чи делеговані токени. Якщо ні — баннер «Активуйте право голосу: делегуйте токени (собі або іншому)».

// iOS — перевірка статусу делегування
func getDelegatee(for address: EthereumAddress) async throws -> EthereumAddress {
    return try await governanceToken.delegates(account: address)
}
// Якщо результат == .zero або == address — ще не делеговано

Push-уведомлення для активних учасників

  • Створено нову пропозицію
  • Голосування скоро закривається (за 24 години)
  • Пропозиція пройшла / відхилена
  • Пропозиція поставлена на виконання
  • Кворум набран

Дозвольте користувачам налаштувати, які уведомлення отримувати — не спамте всіма подіями.

Створення пропозиції

Створення пропозиції Governor — складна операція: необхідно вказати targets (адреси контрактів), values (ETH), calldatas (закодовані виклики функцій) та description. Інтерфейс має або спростити через шаблони, або надати конструктор викликів для технічних користувачів.

Перевірте мінімальний поріг токенів (proposalThreshold) заздалегідь та показуйте, чи у користувача достатньо токенів.

Часова шкала

Компонент Часова шкала
Список пропозицій + статуси 1 тиждень
Екран пропозиції з голосами у реальному часі 1 тиждень
On-chain голосування (Governor) 3 дні
Snapshot голосування 3 дні
Делегування голосів 2 дні
Push-уведомлення 3 дні
Створення пропозиції 1 тиждень

MVP (список + голосування + делегування): 3–4 тижні. Повний додаток з створенням пропозицій, історією, аналітикою: 8–12 тижнів.