V2s: Comment utiliser les extrinsics pour la wot?

,

Question basic mais primordiale, comment ça se passe pour executer des extrinsics custom v2s actuellement via la lib polkadot js ?

Faut-il impérativement forker cette lib pour y implémenter de nouvelles méthodes correspondants aux bon extrinsics ?

Concrètement les 2 extrinsics checker le status membre ou non d’une address, et certifier une address.

Je sais pas comment est fait ton binding dart, mais la lib js polkadot/api permet déjà de faire n’importe quel call, il suffit d’écrire palletInstanceName.callName().
Les fonctions sont générées dynamiquement à partir des métadonnées récupérées via l’api RPC, c’est l’une des premières requêtes que fait la lib au démarrage.

1 « J'aime »

Ok, je regarderai, je sais à minima que je peux exécuter n’importe quelle fonction JS via le SDK.

Comme je ne suis pas un pro du javascript, c’est cool si quelqu’un peu m’aider en donnant quelques exemples de code JS pour:

  • certifier
  • vérifier le statut de membre
  • Récupérer le nombre de certifications reçus/émises

Ou au moins le nom des extrinsics concernés, et leurs paramètres, je ne sais pas où trouver ça facilement.
Pour le reste, je m’occuperais du binding Dart via le SDK que j’ai forké.

Ce n’est pas dans mes priorités tout de suite, mais je prend un peu d’avance en vous demandant ça.
Sinon je creuserais plus le moment venu.

1 « J'aime »

Dans polkadotjs tu à tout les extrinsics :slight_smile:

Sinon j’ai justement codé quelque chose qui génère la liste des extrinsics dans une doc markdown, je comptais le dévoiler aux RML mais bon, c’est la:

4 « J'aime »

Ah trop cool ! Merci ^^

Trop bien ton doc !

1 « J'aime »

Bon ça contient que les call, donc pour réaliser une action utilisateur.

Ça tu ne peux pas le faire en soumettant un extrinsic, ça demande de savoir lire dans le storage onchain, je vais justement expliquer comment fonctionne le storage on-chain lors des RML, car ça me semble être un aspect fundamental à maîtriser que ce soit pour développer un wallet ou pour contribuer à duniter-v2s :slight_smile:

Je n’ai pas encore de doc markdown qui liste les storage item, c’est justement un travail en cours…

De la même façon que pour les call, la lib js polkadot-api te permet de lire n’importequel storage item, elle génère dynamiquement une fonction pour chaque storage item :slight_smile:

2 « J'aime »

Pour ma part, je récupère la liste des données dans le storage depuis polkadot.js :

  • Le menu developer/chainstate/storage liste les variables de stockage (mais les noms ne sont pas bon pour mes appels python, je dois commencer par une majuscule) et permet de requêter leur valeur.
  • L’appel RPC state.getMetadata(at) qui renvoie toute la liste avec le typage (je le fais dans polkadot.js pour avoir le nom exact AVEC la majuscule).
3 « J'aime »

Il y a quelque chose que je ne dois pas comprendre:

Dans le menu /extrinsics de polkadot.js, j’ai créé une identité depuis Bob vers Geck2.

Ensuite, je souhaite confirmer mon identité en tant que Geck2, en donnant mon idtyName, et j’ai une erreur « Identity Not Found »:


ici on voit que l’identité existe déjà


Et là qu’elle n’existe pas …

Pourtant elle existe puisqu’elle a un index

SI j’essai de « valider » l’identité avec cet idtyIndex, j’ai un « Bad Origin »:

?


Edit: En essayant avec d’autres address, ça a fonctionné, mais je ne comprends toujours pas pourquoi ça ne marchait pas sur cette address, on aurait dit un bug, mais je ne sais pas si c’est côté polkadot.js ou duniter … Ou alors que mon identité avait expiré, amis dans ce cas le message d’erreur pourrait être plus explicite, et je devrait pouvoir la renouveler.


Edit2: Je crois avoir compris, c’est bien que la création d’identité avait expiré.
Du coup, identity.identityIndexOf(address) renvoi juste null lorsque l’identité est expiré avant que le owner l’ai confirmé, donc je ne peux pas récupérer le status avec identity.identities(idtyIndex).

Et je n’arrive pas à en recréer pour une address dont une identité précédente a expiré.
Je sais pas si je suis clair … Je ne doit pas regarder les bon états dans le storage je présume.

2 « J'aime »

Ça c’est normal, tu ne peux pas valider une identité, elle est automatiquement validée lorsque toute les conditions sont réunies (confirmation du propriétaire et 5 certif reçues).

Attention polkadot.js affiche tout les call du runtime, y compris ceux qui ne peuvent pas être appelés par l’utilisateur. C’est pourquoi il faut te fier à la liste des user call que je donne dans la doc: docs/api/runtime-calls.md · master · nodes / rust / Duniter v2S · GitLab

Il y a plein de call que l’utilisateur ne peut pas appeler, mais qui sont quand même dans les metadata du runtime, et donc quand même affichés par polkadot.js pour rien.

Non ce n’est pas possible, lorsque la demande de création d’identité expire, la demande est retirée du storage onchain, ce qui est nécessaire pour proteger le sotrage contre le spam, can aucune certification n’est encore requise à ce stade.
Donc comme il n’y a plus rien dans le storage, je ne peux que générer l’erreur IdtyNotFound.

Si tu ne peux pas récupérer le status, c’est que l’identité n’existe pas. Si tu veux savoir si elle a existée par le passée, il faut utiliser un indexeur, tu expérimentes là le fait que le storage on-chain ne contient que « l’état courant ».

Est-ce que tu essayes bien avec un nom différent ?

3 « J'aime »

Ok, jai compris, merci.

Par contre

C’est carrément au moment où Bob essai de créer une identité pour Geck2, alors que Geck2 a déjà eu une identité de Alice, mais expiré. Donc pas de Nom à ce moment là.
Une fois la chance de Geck2 passé, plus possible de se refaire déclarer un idty.

Donc à l’extrinsic create_idty ? Quelle erreur à tu lors de ce call ?

J’ai besoin que tu sois précis, sinon je ne peut rien faire :confused:

Là je parle de créer une idty, pas de confirmer, comme dit dans mon message précédent.

Je compris mon soucis du dessus, je ne pouvais pas confirmer car c’était juste expiré, ça c’est bon.

Quand je veux recréer une identité qui a expiré, j’ai ce message d’erreur:

Alors que non elle n’existe plus:

Enfin son index existe toujours, mais il vaut null, je pense que c’est ça le problème.

Du coup je rectifie, je sais qu’un wallet a une identité expiré si

idtyIndex = identity.identityIndexOf(address)
idtyIndex != null && identity.identities(idtyIndex) == null

Il n’empêche que cela ne permet plus de recréer d’identité sur ce compte actuellement.

1 « J'aime »

Merci c’est ça l’info qu’il me manquait :slight_smile:

Svp quand vous avez un problème indiquez-moi systématiquement:

  • Le nom de l’extrinsic appelé
  • Les valeurs que vous avez renseignées pour les paramètres d’entrée (s’il y a lieu)
  • Le nom de l’erreur retournée
  • Le scénario à dérouler avant pour reproduire l’erreur

Alors pour le coup je viens de comprendre ce qui t’arrive, ce n’est pas un bug mais une feature: toute identité supprimée est révoquée, et le AccountId associé ne peut donc plus servir.

L’élagage des IdtyIndex passe par un extrinsic manuel. C’est une stratégie recommandée par substrate et utilisée par la plupart des blockchains substrate, afin de limiter les traitements automatiques.

Cet extrinsic manuel ne peut être exécuté qu’après une longue période (sinon il échoue), pour garantir qu’un AccountId ne peut pas être réutilisé avant longtemps.

1 « J'aime »

D’accords, mais pourquoi ne pas incrémenter cet index lorsqu’on tente de recréer une identité ?

C’est une feature attendu de ne pas pouvoir recréer d’identité sur un compte, même lors de l’expiration rapide d’après la création ?


Autre question rien à voir: Comment faire pour récupérer le idty_name d’une address dans le storage ?

Est-ce identity.identitiesNames(Text): ?
Si oui je ne comprends pas ce qui est attendu en text, pas une address visiblement.

Il est déjà incrémenté.

Oui, en tout cas j’ai codé volontairement ce comportement ainsi. Mais si ça ne convient pas je peux changer ce comportement :slight_smile:

J’ai fait ainsi pour reproduire le comportement de duniter v1 au plus prêt: les clés publiques des identités révoquées ne sont plus utilisables.

Le but est d’empêcher les attaques de phising sur les certifications: si tu te fais dérober ta clé privée, il ne faut pas que le pirate puisse se créer une nouvelle identité avec celle-ci, et se faire passer pour toi.

Bon on pourrait appliquer ça pour les révocations explicites uniquement, mais ça ne gérerait pas les cas des utilisateurs qui laissent trainer leurs clés privées, car ils n’utilisent plus la Ğ1 et qu’ils s’en foutent, or c’est ceux-là qui sont les plus facile à pirater.

Bon on pourrait n’appliquer ça que pour les expirations après confirmation, c’est vrai que si l’identité n’a même pas été confirmée il n’y a pas grand-chose à protéger.

Je suis ok pour changer ce comportement dans le cas précis où l’identité n’a pas été confirmée par son propriétaire. En revanche dès qu’elle est confirmée, il me semble important d’interdire la réutilisation de l’adresse associée.

1 « J'aime »

Tu ne peux pas, il faut passer par un indexer.

Le storage ne contient que les données nécessaires à la vérification et l’application des règles du protocole.
Or on a pas besoin du nom, on a juste besoin de vérifier que le nom n’est pas déjà pris, donc on garde uniquement un hash Blake2_128 :slight_smile:

1 « J'aime »

Je pense à minima qu’il faut distinguer les expirations dû à la non confirmation de l’identité dans les temps, donc qui n’a jamais été membre, des expirations suite au non renouvellement de son identité.

Idem pour l’expiration pour non atteinte des 5 certifs en 2 mois.


En terme c’est assez embêtant de ne pas pouvoir coupler la création d’identité à la première certification, mais pas insurmontable.

Je sais que ce n’est pas possible car on n’a pas encore le idty_name du owner. Ca va faire pas mal de renvoi de balle entre créateur d’idty (qui globalement sera le premier certificateur) et le owner.

La seule solution que je vois serait que le owner publie d’abord un document de demande d’adhésion avec idty_name, pour qu’un membre puisse le certifier et créer son identity au passage, mais on en reviens au spam sur les documents d’adhésions, ça se mort la queue…


Ah d’accord.

Quel intéret ? Le hash va prendre plus de place que le nom lui même dans le storage non ?
C’est juste pour économiser de la place ?

2 « J'aime »

Ok pour le cas de non confirmation par le propriétaire ,

Par contre, j’ai des réserves sur ce cas.

je pense que tu fais erreur ici, la création d’une identité revient déjà à la certifier, comme je te l’avais indiqué plus haut :wink:

Toute clé doit être préfixée par un hash pour garantir une bonne répartition des clés dans l’arbre, c’est lié au fonctionnement du storage substrate, dont je prépare justement la présentation pour les RML16, du coup tu auras plus d’éléments en voyant ma présentation.
Mais pour faire court, ça prend au contraire moins de place de faire ainsi.

Principalement mais pas que, c’est aussi pour designer les choses correctement. Ce n’est pas le role du storage on-chain que de stocker des données qui ne servent qu’aux wallet, c’est le role des indexeurs.

2 « J'aime »

Voila c’est fait:

Par contre, c’est le dernier changement avant le lancement de la ĞDev, là je dois finaliser le runtime !

3 « J'aime »

Lorsque j’essaie de créer l’identité de Vincentux depuis mon compte membre, j’obtiens cette erreur:

Exception: identity.CreatorNotAllowedToCreateIdty

Pourquoi n’ai-je pas le droit de lui créer ?
C’est parce-que j’ai déjà certifié Kapis aujourd’hui (il y a plus d’une heure) ?
Comment voir dans le storage si je suis disposé à créer une idty/certifier ?

Je précise que j’ai bien alimenté son compte de + de 2 GD pour le créer.