Реализация DAO-портала (голосование, предложения) на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация DAO-портала (голосование, предложения) на сайте
Сложная
~2-4 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Реализация DAO-портала (голосование, предложения) на сайте

DAO-портал — веб-интерфейс для управления децентрализованной организацией: создание предложений, голосование токенами, делегирование голосов, исполнение принятых решений через смарт-контракты.

Архитектура DAO

Governance Token (ERC-20 + EIP-2612 для delегации)
         │
Governor Contract (OpenZeppelin Governor)
    ├── Propose (создать предложение)
    ├── CastVote (проголосовать)
    ├── Queue (поставить в очередь Timelock)
    └── Execute (исполнить через Timelock)
         │
Timelock Controller
    └── Target Contracts (Treasury, Protocol)

Governor Contract

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

import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";

contract DAOGovernor is
    Governor, GovernorSettings, GovernorCountingSimple,
    GovernorVotes, GovernorTimelockControl
{
    constructor(
        IVotes _token,
        TimelockController _timelock
    )
        Governor("DAO Governor")
        GovernorSettings(
            1 days,   // voting delay (1 день до старта голосования)
            7 days,   // voting period (7 дней голосование)
            100_000e18  // proposal threshold (нужно 100k токенов)
        )
        GovernorVotes(_token)
        GovernorTimelockControl(_timelock)
    {}

    // 4% токенов нужно для прохождения (quorum)
    function quorum(uint256 blockNumber) public view override returns (uint256) {
        return token.getPastTotalSupply(blockNumber) * 4 / 100;
    }
}

Frontend: создание предложения

import { useWriteContract, useAccount } from 'wagmi';
import { encodeFunctionData } from 'viem';

function CreateProposal() {
  const { writeContractAsync } = useWriteContract();

  const handleSubmit = async (formData: ProposalFormData) => {
    // Кодируем вызов целевого контракта
    const calldata = encodeFunctionData({
      abi: treasuryAbi,
      functionName: 'transfer',
      args: [formData.recipient, formData.amount]
    });

    await writeContractAsync({
      address: GOVERNOR_ADDRESS,
      abi: governorAbi,
      functionName: 'propose',
      args: [
        [TREASURY_ADDRESS],     // targets
        [0n],                   // values (ETH)
        [calldata],             // calldatas
        formData.description    // description (Markdown)
      ]
    });
  };

  return <ProposalForm onSubmit={handleSubmit} />;
}

Frontend: голосование

function VoteOnProposal({ proposalId }) {
  const { writeContractAsync } = useWriteContract();
  const { address } = useAccount();

  // Получить вес голоса на момент снепшота
  const { data: votingPower } = useReadContract({
    address: GOVERNOR_ADDRESS,
    abi: governorAbi,
    functionName: 'getVotes',
    args: [address!, proposalSnapshotBlock]
  });

  const castVote = async (support: 0 | 1 | 2) => {
    // 0 = Against, 1 = For, 2 = Abstain
    await writeContractAsync({
      address: GOVERNOR_ADDRESS,
      abi: governorAbi,
      functionName: 'castVoteWithReason',
      args: [proposalId, support, reason]
    });
  };

  return (
    <div>
      <p>Ваш вес голоса: {formatTokens(votingPower)} токенов</p>
      <button onClick={() => castVote(1)}>За</button>
      <button onClick={() => castVote(0)}>Против</button>
      <button onClick={() => castVote(2)}>Воздержаться</button>
    </div>
  );
}

Индексирование через The Graph

// Получение списка предложений
const PROPOSALS_QUERY = gql`
  query GetProposals($state: String, $first: Int, $skip: Int) {
    proposals(
      where: { state: $state }
      orderBy: createdAt
      orderDirection: desc
      first: $first
      skip: $skip
    ) {
      id
      proposalId
      proposer { id }
      description
      state
      forVotes
      againstVotes
      abstainVotes
      quorum
      startBlock
      endBlock
      createdAt
    }
  }
`;

// Делегирование голосов
async function delegateVotes(delegatee: string) {
  await writeContractAsync({
    address: GOVERNANCE_TOKEN,
    abi: erc20VotesAbi,
    functionName: 'delegate',
    args: [delegatee]
  });
}

Интеграция Snapshot (off-chain голосование)

Для сигнальных голосований без gas-затрат — Snapshot Protocol:

import snapshot from '@snapshot-labs/snapshot.js';

const client = new snapshot.Client712('https://hub.snapshot.org');

// Создать голосование (подписывается кошельком, без транзакции)
await client.proposal(web3, address, {
  space: 'your-dao.eth',
  type: 'single-choice',
  title: 'Принять новую стратегию токенов?',
  body: '## Описание\n\nПолное описание предложения...',
  choices: ['За', 'Против', 'Воздержаться'],
  start: Math.floor(Date.now() / 1000),
  end: Math.floor(Date.now() / 1000) + 7 * 24 * 3600,
  snapshot: await web3.eth.getBlockNumber(),
  plugins: JSON.stringify({}),
  app: 'your-dao-app'
});

Сроки реализации

  • Governor + Timelock + Governance Token контракты — 2–3 недели
  • Frontend (список предложений, голосование, делегирование) — 2–3 недели
  • Индексер + полный портал — 1–2 месяца