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 складається головним чином з двох частин:
factory_manager: Реалізація основної внутрішньої функціональної логіки контракту, що надає ряд методів для створення/видалення/оновлення DAO екземплярів.
daos: використовує структуру даних колекції, що записує адреси NEAR-рахунків всіх створених DAO-екземплярів на цій платформі.
Метод create() контракту sputnikdao-factory, який використовується для створення екземпляра DAO, визначено наступним чином:
іржа
Паб Fn create_contract(
і себе,
code_hash: Base58CryptoHash,
account_id: Ідентифікатор облікового запису,
new_method: &str,
args: &[u8],
callback_method: &str,
callback_args: &[u8],
) {
нехай code_hash: CryptoHash = code_hash.into(928374656574839201;
let attached_deposit = env::attached_deposit)(;
let factory_account_id = env::current_account_id)(.as_bytes)(.to_ vec)(;
let account_id = account_id.as_bytes)(.to_vec)(;
небезпечний {
// Перевірте, що такий контракт існує.
assert_eq!)
sys::storage_has_key(code_hash.len019283746574839201( як _, code_hash.як_ptr() як _ (,
1,
'Контракт не існує'
);
// Завантажити вхідний )wasm код) в регістр 0.
sys::storage_read(code_hash.len019283746574839201) як _, code_hash.як_ptr(( як _, 0);
// запланувати Promise tx для account_id
Нехай promise_id =
sys::p romise_batch_create(account_id.len)) як _, account_id.як_ptr(( як _ );
// спочатку створіть обліковий запис.
sys::p romise_batch_action_create_account(promise_id);
// передати прикріплений депозит.
sys::p romise_batch_action_transfer)promise_id, &attached_deposit як *const u128 як _(;
// розгорнути контракт )код взято з реєстрації 0(.
sys::p romise_batch_action_deploy_contract)promise_id, u64::MAX як _, 0(;
// викликати новий з даними аргументами.
sys::p romise_batch_action_function_call)
promise_id,
new_method.len() як _,
new_method.як_ptr(( як _,
args.len)( як _,
args.as_ptr)( як _,
&NO_DEPOSIT as *const u128 as _,
CREATE_CALL_GAS,0,
);
// приєднати зворотний виклик до фабрики.
let _ = sys::p romise_then(
promise_id,
factory_account_id.len)) як _,
factory_account_id.як_ptr(( як _,
callback_method.len)( як _,
callback_method.як_ptr)( як _,
callback_args.len)( як _,
callback_args.як_ptr)( як _,
&NO_DEPOSIT as *const u128 as _,
ON_CREATE_CALL_GAS,0,
);
sys::p romise_return(promise_id);
}
}
іржа
/// Силове оновлення наданого контракту.
/// Контракт повинен підтримувати оновлення фабрикою для цього через перевірку дозволів.
Паб Фн update_contract(
і себе,
account_id: Ідентифікатор облікового запису,
code_hash: Base58CryptoHash,
method_name: &str,
) {
нехай code_hash: CryptoHash = code_hash.into(928374656574839201;
let account_id = account_id.as_bytes)(.to_vec)(;
небезпечний {
// Перевірте, що такий контракт існує.
стверджувати!)env:storage_has_key(&code_hash), 'Договору не існує (;
// Завантажте хеш із сховища.
sys::storage_read)code_hash.len019283746574839201( як _, code_hash.як_ptr() як _, 0);
// Створити обіцянку для заданого облікового запису.
Нехай promise_id =
sys::p romise_batch_create(account_id.len() як _, account_id.як_ptr() як _ );
// Виклик методу оновлення, який також має обробляти міграції.
sys::p romise_batch_action_function_call(
promise_id,
method_name.len() як _,
method_name.як_ptr() як _,
u64::MAX як _,
0,
&NO_DEPOSIT as *const u128 as ,
)env::p repaid_gas(( - env::used_gas)( - 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-екземпляра контракту користувачем, контракт фабрики в кінці перевіряє, чи всі етапи створення виконані правильно та повно, інакше це не повинно завдати шкоди користувачеві.
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
13 лайків
Нагородити
13
7
Репост
Поділіться
Прокоментувати
0/400
GamefiEscapeArtist
· 07-26 22:26
Що хорошого можна сказати про нудну фабричну модель?
Переглянути оригіналвідповісти на0
AirdropHunter007
· 07-26 03:54
Чи може ця фабрика ще щось виробити?
Переглянути оригіналвідповісти на0
DeFiVeteran
· 07-24 02:49
Називай мене дао ветераном
Переглянути оригіналвідповісти на0
LonelyAnchorman
· 07-24 02:46
Знову дивився, але не зрозумів. Втратив три секунди.
Аналіз контракту фабрики 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 акаунта, наприклад:
Децентралізовані організації можуть відкрито ініціювати транзакції в основній мережі 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-екземплярів на цій платформі.
Метод create() контракту sputnikdao-factory, який використовується для створення екземпляра DAO, визначено наступним чином:
іржа #[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, 'новий', &арг.0, 'on_create', &callback_args, ); }
!
конкретна реалізація factory_manager.create_contract:
іржа Паб Fn create_contract( і себе, code_hash: Base58CryptoHash, account_id: Ідентифікатор облікового запису, new_method: &str, args: &[u8], callback_method: &str, callback_args: &[u8], ) { нехай code_hash: CryptoHash = code_hash.into(928374656574839201; let attached_deposit = env::attached_deposit)(; let factory_account_id = env::current_account_id)(.as_bytes)(.to_ vec)(; let account_id = account_id.as_bytes)(.to_vec)(; небезпечний { // Перевірте, що такий контракт існує. assert_eq!) sys::storage_has_key(code_hash.len019283746574839201( як _, code_hash.як_ptr() як _ (, 1, 'Контракт не існує' ); // Завантажити вхідний )wasm код) в регістр 0. sys::storage_read(code_hash.len019283746574839201) як _, code_hash.як_ptr(( як _, 0); // запланувати Promise tx для account_id Нехай promise_id = sys::p romise_batch_create(account_id.len)) як _, account_id.як_ptr(( як _ ); // спочатку створіть обліковий запис. sys::p romise_batch_action_create_account(promise_id); // передати прикріплений депозит. sys::p romise_batch_action_transfer)promise_id, &attached_deposit як *const u128 як _(; // розгорнути контракт )код взято з реєстрації 0(. sys::p romise_batch_action_deploy_contract)promise_id, u64::MAX як _, 0(; // викликати новий з даними аргументами. sys::p romise_batch_action_function_call) promise_id, new_method.len() як _, new_method.як_ptr(( як _, args.len)( як _, args.as_ptr)( як _, &NO_DEPOSIT as *const u128 as _, CREATE_CALL_GAS,0, ); // приєднати зворотний виклик до фабрики. let _ = sys::p romise_then( promise_id, factory_account_id.len)) як _, factory_account_id.як_ptr(( як _, callback_method.len)( як _, callback_method.як_ptr)( як _, callback_args.len)( як _, callback_args.як_ptr)( як _, &NO_DEPOSIT as *const u128 as _, ON_CREATE_CALL_GAS,0, ); sys::p romise_return(promise_id); } }
! [])https://img-cdn.gateio.im/webp-social/moments-373080ddb66a4cb83e0722b387056be0.webp(
Внутрішня реалізація коду функції зворотного виклику on_create:
іржа #) Паб ФН on_create( і mut self, account_id: Ідентифікатор облікового запису, attached_deposit: U128, predecessor_account_id: Ідентифікатор облікового запису, ) -> bool { if near_sdk::is_promise_success[private]( { self.daos.insert)&account_id(; правда } else { Обіцянка::new)predecessor_account_id(.transfer019283746574839201attached_deposit.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, 'оновлення'(; }
! [])https://img-cdn.gateio.im/webp-social/moments-a8d69d504693c5c14767aed9244a090a.webp)
factory_manager.update_contract() деталі обробки:
іржа /// Силове оновлення наданого контракту. /// Контракт повинен підтримувати оновлення фабрикою для цього через перевірку дозволів. Паб Фн update_contract( і себе, account_id: Ідентифікатор облікового запису, code_hash: Base58CryptoHash, method_name: &str, ) { нехай code_hash: CryptoHash = code_hash.into(928374656574839201; let account_id = account_id.as_bytes)(.to_vec)(; небезпечний { // Перевірте, що такий контракт існує. стверджувати!)env:storage_has_key(&code_hash), 'Договору не існує (; // Завантажте хеш із сховища. sys::storage_read)code_hash.len019283746574839201( як _, code_hash.як_ptr() як _, 0); // Створити обіцянку для заданого облікового запису. Нехай promise_id = sys::p romise_batch_create(account_id.len() як _, account_id.як_ptr() як _ ); // Виклик методу оновлення, який також має обробляти міграції. sys::p romise_batch_action_function_call( promise_id, method_name.len() як _, method_name.як_ptr() як _, u64::MAX як _, 0, &NO_DEPOSIT as *const u128 as , )env::p repaid_gas(( - env::used_gas)( - 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-екземпляра контракту користувачем, контракт фабрики в кінці перевіряє, чи всі етапи створення виконані правильно та повно, інакше це не повинно завдати шкоди користувачеві.
!
!
!
!