Interprétation du contrat de la fabrique Sputnik DAO
1. Contrat d'usine Sputnik-DAO
Sputnik-DAO utilise le modèle de conception de fabrique créatif pour réaliser la création et la gestion unifiée de l'organisation autonome décentralisée (DAO) sur cette plateforme.
Cet article présentera en détail la conception et la mise en œuvre du modèle d'usine de la plateforme Sputnik-DAO (sputnikdao-factory).
Le dépôt de code source correspondant au contrat est situé à :
2. Présentation des fonctionnalités du module DAPP
La page DAPP de la plateforme Sputnik DAO a déjà vu de nombreux organisations autonomes décentralisées créer et personnaliser leurs propres objets d'instance DAO ( contrat ) Sputnikdaov2.
Jusqu'en mars 2022, le DAO le plus actif créé sur cette plateforme est news.sputnik-dao.near, avec 3051 propositions (propositions) en cours de vote public ou ayant été clôturées.
En explorant NEAR Explorer, il est possible de découvrir que les contrats des instances DAO de cette plateforme sont déployés de manière unifiée par le contrat NEAR sputnik-dao.near( et le contrat sputnikdao-factory).
C'est-à-dire que tous les contrats d'instance DAO créés sur la plateforme Sputnik DAO sont déployés sous les sous-comptes de ce compte NEAR, par exemple:
pcp.sputnik-dao.near
test-dao-bro.sputnik-dao.near
blaqkstereo.sputnik-dao.near
octopode-dao.sputnik-dao.near
Les organisations décentralisées peuvent initier des transactions publiquement sur le réseau principal NEAR, en utilisant la méthode create() fournie par le contrat sputnikdao-factory pour créer de nouvelles instances de DAO.
3. Interprétation du code du contrat sputnikdao-factory
3.1 Créer un DAO
L'état du contrat sputnikdao-factory est principalement composé des deux parties suivantes :
factory_manager: Implémentation de la logique fonctionnelle interne principale du contrat, fournissant une série de méthodes pour créer/supprimer/mettre à jour des instances de DAO.
daos : utilise une structure de données en ensemble, enregistrant les adresses de compte NEAR de toutes les instances de DAO créées dans l'historique de la plateforme.
La méthode create() du contrat sputnikdao-factory utilisée pour créer une instance de DAO est définie comme suit :
implémentation spécifique de factory_manager.create_contract :
rouille
pub fn create_contract(
&self,
code_hash: Base58CryptoHash,
account_id: AccountId,
new_method: &str,
args: &[u8],
callback_method: &str,
callback_args: &[u8],
) {
let code_hash: CryptoHash = code_hash.into();
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();
unsafe {
// Vérifiez que ce contrat existe.
assert_eq!(
sys::storage_has_key(code_hash.len() as _, code_hash.as_ptr() as _),
1,
'Le contrat n'existe pas'
);
// Charger le code wasm d'entrée ( dans le registre 0.
sys::storage_read)code_hash.len(( as _, code_hash.as_ptr)( as _, 0);
// planifier une transaction Promise pour account_id
let promise_id =
sys::promise_batch_create)account_id.len(( comme _, account_id.as_ptr)( comme _);
// créez d'abord un compte.
sys::promise_batch_action_create_account)promise_id(;
// transférer le dépôt joint.
sys::promise_batch_action_transfer)promise_id, &attached_deposit as *const u128 as _(;
// déployer le contrat ) le code est pris à partir de l'enregistrement 0(.
sys::promise_batch_action_deploy_contract)promise_id, u64::MAX comme _, 0(;
// appeler nouveau avec les arguments donnés.
sys::promise_batch_action_function_call)
promise_id,
new_method.len(( comme _,
new_method.as_ptr)( as _,
args.len)( as _,
args.as_ptr)( as _,
&NO_DEPOSIT as *const u128 as _,
CREATE_CALL_GAS.0,
);
// attacher un rappel à l'usine.
let _ = sys::promise_then)
promise_id,
factory_account_id.len(( as _,
factory_account_id.as_ptr)( as _,
callback_method.len)( as _,
callback_method.as_ptr)( as _,
callback_args.len)( as _,
callback_args.as_ptr)( as _,
&NO_DEPOSIT as *const u128 as _,
ON_CREATE_CALL_GAS.0,
);
sys::promise_return)promise_id(;
}
}
L'interface de contrat fournie par le contrat de l'usine update###( :
rouille
/// Tente de mettre à jour le compte donné créé par cette usine avec le code spécifié.
pub fn update)&self, account_id: AccountId, code_hash: Base58CryptoHash( {
let caller_id = env::predecessor_account_id)(;
assert!)
caller_id == self.get_owner(( || caller_id == account_id,
'Doit être mis à jour par le propriétaire de l'usine ou le DAO lui-même'
);
assert!)
self.daos.contains(&account_id(,
'Doit être un contrat créé par la fabrique'
);
self.factory_manager
.update_contract)account_id, code_hash, 'update'(;
}
factory_manager.update_contract)( détails du traitement:
rouille
/// Force la mise à jour du contrat donné.
/// Le contrat doit prendre en charge la mise à jour par la fabrique via une vérification des autorisations.
pub fn update_contract)
&self,
account_id: AccountId,
code_hash: Base58CryptoHash,
method_name: &str,
( {
let code_hash: CryptoHash = code_hash.into)(;
let account_id = account_id.as_bytes)(.to_vec)(;
unsafe {
// Vérifiez que ce contrat existe.
assert!)env::storage_has_key(&code_hash(, 'Le contrat n'existe pas');
// Charger le hachage depuis le stockage.
sys::storage_read)code_hash.len(( as _, code_hash.as_ptr)( as _, 0);
// Créer une promesse envers le compte donné.
let promise_id =
sys::promise_batch_create)account_id.len(( as _, account_id.as_ptr)( as _);
// Appeler la méthode de mise à jour, qui devrait également gérer les migrations.
sys::promise_batch_action_function_call)
promise_id,
method_name.len(( as _,
method_name.as_ptr)( as _,
u64::MAX as _,
0,
&NO_DEPOSIT as *const u128 as _,
)env::prepaid_gas(( - env::used_gas)( - GAS_UPDATE_LEFTOVER).0,);
sys::promise_return)promise_id(;
}
}
4. Analyse de la sécurité des contrats de la Fabrique Sputnik-DAO
La sécurité du contrat de la Fabrique Sputnik-DAO est principalement garantée par les aspects suivants :
Contrôle des accès : Les méthodes de type view ouvertes par le contrat ne doivent pas modifier les variables d'état du contrat, c'est-à-dire que le premier paramètre de la définition de la méthode doit être défini comme &self, et non &mut self.
Contrôle d'accès : Les fonctions privilégiées ouvertes du contrat, qui ne peuvent être exécutées que par le propriétaire du contrat ) ou le compte du contrat DAO (, et il existe des assertions correspondantes dans la méthode.
Gestion des erreurs : Le contrat de la Factory Sputnik-DAO a mis en place des mécanismes de gestion des erreurs raisonnables pour toutes les situations d'exception possibles. Par exemple, lorsque l'utilisateur utilise le contrat de la Factory pour créer une nouvelle instance de contrat DAO, il vérifiera à la fin que toutes les étapes de création se sont déroulées normalement et complètement, sinon cela ne devrait pas causer de perte à l'utilisateur.
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
13 J'aime
Récompense
13
7
Reposter
Partager
Commentaire
0/400
GamefiEscapeArtist
· 07-26 22:26
Qu'est-ce qu'il y a à dire sur le modèle d'usine ennuyeux?
Voir l'originalRépondre0
AirdropHunter007
· 07-26 03:54
Cette usine peut-elle encore produire un peu ?
Voir l'originalRépondre0
DeFiVeteran
· 07-24 02:49
Appelez-moi le vétéran dao
Voir l'originalRépondre0
LonelyAnchorman
· 07-24 02:46
J'ai encore regardé mais je n'ai pas compris, ça m'a fait perdre trois secondes.
Voir l'originalRépondre0
MentalWealthHarvester
· 07-24 02:32
Eh bien, le modèle de fabrication est aussi complexe que ça ?
Analyse des contrats de l'usine Sputnik DAO : mécanismes clés pour créer et mettre à jour un DAO
Interprétation du contrat de la fabrique Sputnik DAO
1. Contrat d'usine Sputnik-DAO
Sputnik-DAO utilise le modèle de conception de fabrique créatif pour réaliser la création et la gestion unifiée de l'organisation autonome décentralisée (DAO) sur cette plateforme.
Cet article présentera en détail la conception et la mise en œuvre du modèle d'usine de la plateforme Sputnik-DAO (sputnikdao-factory).
Le dépôt de code source correspondant au contrat est situé à :
2. Présentation des fonctionnalités du module DAPP
La page DAPP de la plateforme Sputnik DAO a déjà vu de nombreux organisations autonomes décentralisées créer et personnaliser leurs propres objets d'instance DAO ( contrat ) Sputnikdaov2.
Jusqu'en mars 2022, le DAO le plus actif créé sur cette plateforme est news.sputnik-dao.near, avec 3051 propositions (propositions) en cours de vote public ou ayant été clôturées.
En explorant NEAR Explorer, il est possible de découvrir que les contrats des instances DAO de cette plateforme sont déployés de manière unifiée par le contrat NEAR sputnik-dao.near( et le contrat sputnikdao-factory).
C'est-à-dire que tous les contrats d'instance DAO créés sur la plateforme Sputnik DAO sont déployés sous les sous-comptes de ce compte NEAR, par exemple:
Les organisations décentralisées peuvent initier des transactions publiquement sur le réseau principal NEAR, en utilisant la méthode create() fournie par le contrat sputnikdao-factory pour créer de nouvelles instances de DAO.
3. Interprétation du code du contrat sputnikdao-factory
3.1 Créer un DAO
L'état du contrat sputnikdao-factory est principalement composé des deux parties suivantes :
rouille pub struct SputnikDAOFactory { factory_manager: FactoryManager, daos: UnorderedSet\u003caccountid\u003e, }
factory_manager: Implémentation de la logique fonctionnelle interne principale du contrat, fournissant une série de méthodes pour créer/supprimer/mettre à jour des instances de DAO.
daos : utilise une structure de données en ensemble, enregistrant les adresses de compte NEAR de toutes les instances de DAO créées dans l'historique de la plateforme.
La méthode create() du contrat sputnikdao-factory utilisée pour créer une instance de DAO est définie comme suit :
rouille #[payable] pub fn create(&mut self, name: AccountId, args: Base64VecU8) { let account_id: AccountId = format!('{}.{}', name, 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::predecessor_account_id() })) .expect('Échec de la sérialisation'); self.factory_manager.create_contract( self.get_default_code_hash(), account_id, 'nouveau', &args.0, 'on_create', \u0026callback_args, ); }
implémentation spécifique de factory_manager.create_contract :
rouille pub fn create_contract( &self, code_hash: Base58CryptoHash, account_id: AccountId, new_method: &str, args: &[u8], callback_method: &str, callback_args: &[u8], ) { let code_hash: CryptoHash = code_hash.into(); 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(); unsafe { // Vérifiez que ce contrat existe. assert_eq!( sys::storage_has_key(code_hash.len() as _, code_hash.as_ptr() as _), 1, 'Le contrat n'existe pas' ); // Charger le code wasm d'entrée ( dans le registre 0. sys::storage_read)code_hash.len(( as _, code_hash.as_ptr)( as _, 0); // planifier une transaction Promise pour account_id let promise_id = sys::promise_batch_create)account_id.len(( comme _, account_id.as_ptr)( comme _); // créez d'abord un compte. sys::promise_batch_action_create_account)promise_id(; // transférer le dépôt joint. sys::promise_batch_action_transfer)promise_id, &attached_deposit as *const u128 as _(; // déployer le contrat ) le code est pris à partir de l'enregistrement 0(. sys::promise_batch_action_deploy_contract)promise_id, u64::MAX comme _, 0(; // appeler nouveau avec les arguments donnés. sys::promise_batch_action_function_call) promise_id, new_method.len(( comme _, new_method.as_ptr)( as _, args.len)( as _, args.as_ptr)( as _, &NO_DEPOSIT as *const u128 as _, CREATE_CALL_GAS.0, ); // attacher un rappel à l'usine. let _ = sys::promise_then) promise_id, factory_account_id.len(( as _,
factory_account_id.as_ptr)( as _, callback_method.len)( as _, callback_method.as_ptr)( as _, callback_args.len)( as _, callback_args.as_ptr)( as _, &NO_DEPOSIT as *const u128 as _, ON_CREATE_CALL_GAS.0, ); sys::promise_return)promise_id(; } }
![])https://img-cdn.gateio.im/webp-social/moments-373080ddb66a4cb83e0722b387056be0.webp(
Implémentation du code interne de la fonction de rappel on_create :
rouille #) pub fn on_create[private] &mut self, account_id: AccountId, attached_deposit: U128, predecessor_account_id: AccountId, ( -\u003e bool { if near_sdk::is_promise_success)( { self.daos.insert)&account_id(; vrai } else { Promise::new)predecessor_account_id(.transfer)attached_deposit.0(; faux } }
![])https://img-cdn.gateio.im/webp-social/moments-8b462e3ac0fd55e990921d21d66e3d42.webp(
) Mise à jour 3.2 DAO
L'interface de contrat fournie par le contrat de l'usine update###( :
rouille /// Tente de mettre à jour le compte donné créé par cette usine avec le code spécifié. pub fn update)&self, account_id: AccountId, code_hash: Base58CryptoHash( { let caller_id = env::predecessor_account_id)(; assert!) caller_id == self.get_owner(( || caller_id == account_id, 'Doit être mis à jour par le propriétaire de l'usine ou le DAO lui-même' ); assert!) self.daos.contains(&account_id(, 'Doit être un contrat créé par la fabrique' ); self.factory_manager .update_contract)account_id, code_hash, 'update'(; }
![])https://img-cdn.gateio.im/webp-social/moments-a8d69d504693c5c14767aed9244a090a.webp(
factory_manager.update_contract)( détails du traitement:
rouille /// Force la mise à jour du contrat donné. /// Le contrat doit prendre en charge la mise à jour par la fabrique via une vérification des autorisations. pub fn update_contract) &self, account_id: AccountId, code_hash: Base58CryptoHash, method_name: &str, ( { let code_hash: CryptoHash = code_hash.into)(; let account_id = account_id.as_bytes)(.to_vec)(; unsafe { // Vérifiez que ce contrat existe. assert!)env::storage_has_key(&code_hash(, 'Le contrat n'existe pas'); // Charger le hachage depuis le stockage. sys::storage_read)code_hash.len(( as _, code_hash.as_ptr)( as _, 0); // Créer une promesse envers le compte donné. let promise_id = sys::promise_batch_create)account_id.len(( as _, account_id.as_ptr)( as _); // Appeler la méthode de mise à jour, qui devrait également gérer les migrations. sys::promise_batch_action_function_call) promise_id, method_name.len(( as _, method_name.as_ptr)( as _, u64::MAX as _, 0, &NO_DEPOSIT as *const u128 as _, )env::prepaid_gas(( - env::used_gas)( - GAS_UPDATE_LEFTOVER).0,); sys::promise_return)promise_id(; } }
![])https://img-cdn.gateio.im/webp-social/moments-729b65b1335931b4645ff5a9981d125b.webp(
4. Analyse de la sécurité des contrats de la Fabrique Sputnik-DAO
La sécurité du contrat de la Fabrique Sputnik-DAO est principalement garantée par les aspects suivants :
Contrôle des accès : Les méthodes de type view ouvertes par le contrat ne doivent pas modifier les variables d'état du contrat, c'est-à-dire que le premier paramètre de la définition de la méthode doit être défini comme &self, et non &mut self.
Contrôle d'accès : Les fonctions privilégiées ouvertes du contrat, qui ne peuvent être exécutées que par le propriétaire du contrat ) ou le compte du contrat DAO (, et il existe des assertions correspondantes dans la méthode.
Gestion des erreurs : Le contrat de la Factory Sputnik-DAO a mis en place des mécanismes de gestion des erreurs raisonnables pour toutes les situations d'exception possibles. Par exemple, lorsque l'utilisateur utilise le contrat de la Factory pour créer une nouvelle instance de contrat DAO, il vérifiera à la fin que toutes les étapes de création se sont déroulées normalement et complètement, sinon cela ne devrait pas causer de perte à l'utilisateur.
![])https://img-cdn.gateio.im/webp-social/moments-074c1aa0b7f9adfa5780a29c73654fc0.webp(
![])https://img-cdn.gateio.im/webp-social/moments-aebf6315f45abba98b7345259ffe8b5d.webp(
![])https://img-cdn.gateio.im/webp-social/moments-a3a84d139b8950498848a5cafbdfea83.webp(
![])https://img-cdn.gateio.im/webp-social/moments-46f1a89001b11b13b1a8d1b484d4877d.webp(