Разработка мультисиг-управления казначейством DAO

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка мультисиг-управления казначейством DAO
Сложная
~1-2 недели
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка NFT-доступа для членов DAO

NFT-членство — альтернатива токен-взвешенному governance. Вместо «1 токен = 1 голос» работает «1 NFT = 1 голос» или «владение NFT = доступ». Это решает часть проблем plutocracy: крупный холдер не имеет автоматического доминирования. MolochDAO, Guild.xyz, Friends With Benefits — примеры систем, где membership определяется NFT или whitelist, а не просто балансом токенов.

Технически задача делится на два блока: сам NFT-membership контракт и система контроля доступа, которая проверяет владение NFT при каждой защищённой операции.

Membership NFT контракт

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract DAOMembershipNFT is ERC721, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    // Soulbound: NFT нельзя передавать
    bool public isSoulbound;

    // Merkle root для whitelist-минтинга
    bytes32 public merkleRoot;

    uint256 private _tokenIdCounter;
    uint256 public maxSupply;

    // Tier системa: 1 = Member, 2 = Core, 3 = Founder
    mapping(uint256 => uint8) public memberTier;
    mapping(address => bool) public hasMinted;

    event MemberAdded(address indexed member, uint256 tokenId, uint8 tier);
    event MemberRevoked(uint256 indexed tokenId);

    constructor(
        string memory name,
        string memory symbol,
        uint256 _maxSupply,
        bool _soulbound
    ) ERC721(name, symbol) {
        maxSupply = _maxSupply;
        isSoulbound = _soulbound;
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
    }

    // Mintинг через Merkle proof (для whitelist launch)
    function mintWithProof(
        bytes32[] calldata proof,
        uint8 tier
    ) external {
        require(!hasMinted[msg.sender], "Already minted");
        require(_tokenIdCounter < maxSupply, "Max supply reached");

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender, tier));
        require(MerkleProof.verify(proof, merkleRoot, leaf), "Invalid proof");

        hasMinted[msg.sender] = true;
        _mintMember(msg.sender, tier);
    }

    // Минтинг через governance решение
    function mintByGovernance(
        address to,
        uint8 tier
    ) external onlyRole(MINTER_ROLE) {
        require(!hasMinted[to], "Already has membership");
        _mintMember(to, tier);
    }

    function _mintMember(address to, uint8 tier) internal {
        uint256 tokenId = ++_tokenIdCounter;
        memberTier[tokenId] = tier;
        _safeMint(to, tokenId);
        emit MemberAdded(to, tokenId, tier);
    }

    // Soulbound: блокировка transfer
    function _beforeTokenTransfer(
        address from, address to, uint256 tokenId, uint256 batchSize
    ) internal override {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
        if (isSoulbound && from != address(0) && to != address(0)) {
            revert("Soulbound: non-transferable");
        }
    }

    // Отзыв членства через governance (burn)
    function revoke(uint256 tokenId) external onlyRole(MINTER_ROLE) {
        address owner = ownerOf(tokenId);
        hasMinted[owner] = false;
        _burn(tokenId);
        emit MemberRevoked(tokenId);
    }
}

Soulbound vs передаваемые NFT

Soulbound (ERC-5192) — NFT нельзя продать или передать. Членство привязано к личности, не к капиталу. Подходит для DAO, где важна реальная идентичность участников (contributor DAO, professional guilds). Минус: если ключ потерян — нет способа перенести членство без governance голосования.

Передаваемые membership NFT — работают как коллекционные токены доступа (например, Nouns DAO). Можно продать место в DAO. Более ликвидны, создают market price для членства. Риск: спекулятивный рынок может исказить состав DAO.

Tier-система

Одного «да/нет» недостаточно для сложных DAO. Tier-уровни дают гибкость:

Tier Название Права Условия получения
1 Observer Чтение закрытых обсуждений Whitelist mint
2 Member Голосование, proposals Активность 30+ дней
3 Core Grants committee, veto Выбор голосованием
4 Founder Treasury multi-sig Только founding team

Повышение tier через governance proposal: любой член Tier 2 может номинировать другого на Tier 3. Governor голосует, по итогам MINTER_ROLE минтует upgrade.

On-chain верификация владения

Контроль доступа к DAO функциям через балансовую проверку:

contract DAOGovernanceWithNFT {
    DAOMembershipNFT public membershipNFT;

    modifier onlyMember() {
        require(membershipNFT.balanceOf(msg.sender) > 0, "Not a member");
        _;
    }

    modifier onlyTier(uint8 minTier) {
        uint256 balance = membershipNFT.balanceOf(msg.sender);
        require(balance > 0, "Not a member");

        // Находим максимальный tier владельца
        uint8 highestTier = _getHighestTier(msg.sender);
        require(highestTier >= minTier, "Insufficient tier");
        _;
    }

    function createProposal(...) external onlyMember() { ... }
    function accessTreasury(...) external onlyTier(3) { ... }

    function _getHighestTier(address member) internal view returns (uint8) {
        uint256 balance = membershipNFT.balanceOf(member);
        uint8 highest = 0;
        // Для небольших DAO (< 1000 членов) можно итерировать
        for (uint256 i = 0; i < balance; i++) {
            uint256 tokenId = membershipNFT.tokenOfOwnerByIndex(member, i);
            uint8 tier = membershipNFT.memberTier(tokenId);
            if (tier > highest) highest = tier;
        }
        return highest;
    }
}

Для DAO с тысячами членов итерация в on-chain функции — проблема. Альтернатива: хранить mapping address => uint8 tier в контракте, обновляемый при минт/burn.

Off-chain верификация через подпись

Для доступа к закрытым Discord каналам, внутренним сайтам или off-chain ресурсам — верификация через wallet signature без транзакции:

// Frontend: пользователь подписывает сообщение
const message = `Verify DAO membership\nTimestamp: ${Date.now()}\nAddress: ${address}`;
const signature = await signer.signMessage(message);

// Backend: проверка подписи + ownership
async function verifyMembership(address: string, signature: string): Promise<boolean> {
  // Восстанавливаем адрес из подписи
  const recovered = ethers.verifyMessage(message, signature);
  if (recovered.toLowerCase() !== address.toLowerCase()) return false;

  // Проверяем баланс NFT через RPC
  const nft = new ethers.Contract(NFT_ADDRESS, ABI, provider);
  const balance = await nft.balanceOf(address);
  return balance.gt(0);
}

Этот паттерн используется в Guild.xyz и Collab.Land для Discord gate-inга. Пользователь не платит gas, просто подписывает — и получает роль в Discord при наличии NFT.

Процесс работы

Проектирование (3-5 дней). Tier структура, soulbound vs transferable, launch механика (Merkle whitelist, публичный mint, только governance), интеграция с существующим Governor или новый.

Разработка контрактов (1,5-2 недели). Membership NFT + governance integration + тесты.

Off-chain интеграция (1 неделя). Backend верификация, Discord/Telegram bot через Collab.Land или кастомный.

Аудит (1 неделя). NFT контракты с access control функциями требуют аудита, особенно revoke логика.

Сроки и стоимость — после детализации требований.