Анализ контрактов фабрики Sputnik DAO: основные механизмы создания и обновления DAO

Интерпретация контракта фабрики Sputnik DAO

1. Sputnik-DAO фабричный контракт

Sputnik-DAO использует модель проектирования фабрики для реализации единого создания и управления децентрализованной автономной организацией (DAO) на этой платформе.

В данной статье подробно рассматривается реализация дизайна фабричной модели Sputnik-DAO платформы (sputnikdao-factory).

Исходный код соответствующего контракта находится в:

!

2. Введение в функциональность модуля DAPP

На платформе Sputnik DAO на странице DAPP уже было создано и настроено немало децентрализованных автономных организаций, которые создали свои собственные экземпляры DAO ( контракта Sputnikdaov2 ).

По состоянию на март 2022 года, самым активным DAO на этой платформе является news.sputnik-dao.near, в котором уже 3051 предложение (proposals) находится на открытом голосовании или статус завершен.

Исследуя через NEAR Explorer, можно обнаружить, что контракты различных DAO экземпляров на этой платформе развертываются централизованно через контракт NEAR аккаунта sputnik-dao.near( и контракт sputnikdao-factory).

То есть все контракты экземпляров DAO, созданные на платформе Sputnik DAO, развертываются в подаккаунтах этой учетной записи NEAR, например:

  • pcp.sputnik-dao.near
  • test-dao-bro.sputnik-dao.near
  • blaqkstereo.sputnik-dao.near
  • octopode-dao.sputnik-dao.near

Децентрализованные организации могут публично инициировать транзакции в основной сети NEAR, вызывая метод create(), предоставляемый контрактом sputnikdao-factory, для создания нового экземпляра DAO.

!

3. Разбор кода контракта sputnikdao-factory

3.1 Создание DAO

состояние контракта sputnikdao-factory состоит в основном из следующих двух частей:

ржавчина pub struct SputnikDAOFactory { factory_manager: FactoryManager, daos: UnorderedSet, }

  • factory_manager: Основная внутренняя функциональная логика контракта, предоставляющая ряд методов для создания/удаления/обновления экземпляров DAO.

  • daos: использует структуру данных множества, записывающую адреса NEAR аккаунтов всех созданных экземпляров DAO на платформе.

Метод контракта sputnikdao-factory, используемый для создания экземпляра DAO, create(), определяется следующим образом:

ржавчина #[payable] pub fn create(&mut self, name: AccountId, args: Base64VecU8) { let account_id: AccountId = format!('{}. {}', имя, env::current_account_id()) .parse() .unwrap(); let callback_args = serde_json::to_vec(&json!({ 'account_id': account_id, 'attached_deposit': U128(env::attached_deposit()), 'predecessor_account_id': env::p redecessor_account_id() })) .expect('Не удалось сериализовать'); self.factory_manager.создать_contract( self.get_default_code_hash(), account_id, 'новый', &args.0, «on_create», &callback_args, ); }

!

конкретная реализация factory_manager.create_contract:

ржавчина паб fn create_contract( и себя, code_hash: Base58CryptoHash, account_id: AccountId, new_method: &str, args: &[u8], callback_method: &str, callback_args: &[u8], ) { пусть code_hash: CryptoHash = code_hash.into(); let attached_deposit = env::attached_deposit(); let factory_account_id = env::current_account_id().as_bytes().to_ vec(); пусть account_id = account_id.as_bytes().to_vec(); небезопасно { // Проверьте, существует ли такой контракт. assert_eq!( sys::storage_has_key(code_hash.len() as _, code_hash.as_ptr() as _ ), 1, 'Контракт не существует' ); // Загрузить ввод (wasm код) в регистр 0. sys::storage_read(code_hash.len() as _, code_hash.as_ptr() as _, 0); // запланируйте Promise tx на account_id пусть promise_id = sys::p romise_batch_create(account_id.len() как _, account_id.as_ptr() как _ ); // сначала создайте аккаунт. sys::p romise_batch_action_create_account(promise_id); // перевести вложенный депозит. sys::p romise_batch_action_transfer(promise_id, &attached_deposit as *const u128 as _); // развернуть контракт ( код взят из реестра 0). sys::p romise_batch_action_deploy_contract(promise_id, u64::MAX as _, 0); // вызовите новый с заданными аргументами. sys::p romise_batch_action_function_call( promise_id, new_method.len() как _, new_method.as_ptr() как _, args.len() как _, args.as_ptr() как _, &NO_DEPOSIT как *const u128 как _, CREATE_CALL_GAS.0, ); // прикрепить обратный вызов к фабрике. let _ = sys::p romise_then( promise_id, factory_account_id.len() как _, factory_account_id.as_ptr() как _, callback_method.len() как _, callback_method.as_ptr() как _, callback_args.len() как _, callback_args.as_ptr() как _, &NO_DEPOSIT как *const u128 как _, ON_CREATE_CALL_GAS.0, ); sys::p romise_return(promise_id); } }

!

Внутренняя реализация кода функции обратного вызова on_create:

ржавчина #[private] паб fn on_create( &mut self, account_id: AccountId, attached_deposit: U128, predecessor_account_id: AccountId, ) -> bool { if near_sdk::is_promise_success() { self.daos.insert(&account_id); правда } иначе { Promise::new(предшествующий_идентификатор_аккаунта).transfer(прикрепленный_депозит.0); ложный } }

!

3.2 обновление DAO

Контрактный интерфейс, предоставленный фабричным контрактом update():

ржавчина /// Пытается обновить данный аккаунт, созданный этой фабрикой, до указанного кода. pub fn update(&self, account_id: AccountId, code_hash: Base58CryptoHash) { let caller_id = env::p redecessor_account_id(); утверждать!( caller_id == self.get_owner() || caller_id == account_id, 'Должен быть обновлен владельцем фабрики или самим DAO' ); утверждать!( self.daos.contains(&account_id), 'Должен быть контракт, созданный фабрикой' ); self.factory_manager .update_contract(account_id, code_hash, 'обновить'); }

!

factory_manager.update_contract() обработка деталей:

ржавчина /// Принудительное обновление данного контракта. /// Контракт должен поддерживать обновление через фабрику с проверкой разрешений. паб fn update_contract( и себя, account_id: AccountId, code_hash: Base58CryptoHash, method_name: &str, ) { пусть code_hash: CryptoHash = code_hash.into(); пусть account_id = account_id.as_bytes().to_vec(); небезопасно { // Проверьте, что такой контракт существует. assert!(env::storage_has_key(&code_hash), 'Контракт не существует'); // Загрузите хэш из хранилища. sys::storage_read(code_hash.len() as _, code_hash.as_ptr() as _, 0); // Создать обещание к заданному счету. пусть promise_id = sys::p romise_batch_create(account_id.len() как _, account_id.as_ptr() как _ ); // Вызовите метод обновления, который также должен обрабатывать миграции. sys::p romise_batch_action_function_call( promise_id, method_name.len() как _, method_name.as_ptr() как _, u64::MAX как _, 0, &NO_DEPOSIT как *const u128 как _, (env::предоплаченный_газ() - env::использованный_газ() - GAS_UPDATE_LEFTOVER).0,); sys::p romise_return(promise_id); } }

!

4. Анализ безопасности контракта Sputnik-DAO Factory

Безопасность контракта Sputnik-DAO Factory обеспечивается в основном следующими аспектами:

  • Контроль доступа: открытые методы типа view контракта не должны изменять переменные состояния контракта, то есть первый параметр в определении метода должен быть установлен как &self, а не &mut self.

  • Контроль доступа: Привилегированные функции контракта, которые могут быть выполнены только владельцем контракта ( или аккаунтом контракта DAO ), и в методах присутствуют соответствующие утверждения.

  • Обработка ошибок: Контракт фабрики Sputnik-DAO реализует соответствующие разумные механизмы обработки ошибок для возможных исключительных ситуаций. Например, при создании нового экземпляра контракта DAO с использованием фабрики, в конце будет проверено, что все шаги создания были выполнены нормально и полностью; в противном случае пользователю не должны быть причинены убытки.

!

!

!

!

SYS-2.62%
Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • 7
  • Репост
  • Поделиться
комментарий
0/400
GamefiEscapeArtistvip
· 07-26 22:26
Что хорошего в скучной фабричной модели?
Посмотреть ОригиналОтветить0
AirdropHunter007vip
· 07-26 03:54
Этот завод еще может немного поработать?
Посмотреть ОригиналОтветить0
DeFiVeteranvip
· 07-24 02:49
Назови меня дао-ветераном
Посмотреть ОригиналОтветить0
LonelyAnchormanvip
· 07-24 02:46
Снова посмотрел, но не понял. Потратил три секунды.
Посмотреть ОригиналОтветить0
MentalWealthHarvestervip
· 07-24 02:32
Ничего себе, фабричный метод настолько сложен?
Посмотреть ОригиналОтветить0
BakedCatFanboyvip
· 07-24 02:22
Пригласите кого-нибудь перевести, я запутался.
Посмотреть ОригиналОтветить0
  • Закрепить