RFC pour les dérivations des HD Wallets dans Duniter V2S

RFC publiée sur rfc/0019_Duniter_V2_derivation_path_convention_hd_wallets.md · feature/protocol-v2s · documents / RFCs · GitLab

Duniter V2S conventions for Hierarchical Deterministic Wallet

Master seed generation

Master seed should be generated from a BIP-39-Mnemonic.

Key derivation

Key derivation should use Substrate-Derivation-Path specifications.

Key derivation scheme

First derivation step should be an hardened derivation and represent an account_id.

<mnemonic>//<account_id>

account_id is an integer beetween 0 and (2^24) - 1.

There are 3 types of accounts :

Account type account_id value conditions
Member account_id == 0
Transparent account_id != 0 && account_id % 2 == 0
Opaque account_id % 2 == 1
  • Transparent: Classic non-member wallet (even)
  • Opaque: A wallet using single-use public keys for each payment received and for each payment to oneself (odd).

Opaque account derivation scheme

For self-payment, it is first necessary to derive the so-called « internal keypair », by derivation //1 from the opaque account keypair.

<mnemonic>//<account_id>//1

Then, each single-use public key is obtained by soft derivation of the « internal public key ».

<mnemonic>//<account_id>//1/i

Where i is the payment to oneself number, beginning from 1.

For external payments, it is first necessary to derive the so-called « external keypair », by derivation //0 from the opaque account keypair.

<mnemonic>//<account_id>//0

Then, each single-use public key is obtained by soft derivation of the « external public key ».

<mnemonic>//<account_id>//0/i

Where i is the public key derivation number, beginning from 1.

Examples

Example 1

Mnemonic: "acquire flat utility climb filter device liberty beyond matrix satisfy metal essence"
Seed: 0xc7de9b8c771078445f31b7e7ce0ef58b588ac37f85359527b7267ac3ad2d25f5
Address: 5HBUc4C28AWThgPZ47TKoY9RTebMJbkfrLKWveWH6EzfAye4

Account ID: 1
Type: Opaque

First External Public Key
Path: "acquire flat utility climb filter device liberty beyond matrix satisfy metal essence//1/0/1"
Address: 5CcNUmAo5P4K9LC68fgqFKNDTcxZ7zheLeLgk4mnADXeor2K

Third External Public Key
Path: "acquire flat utility climb filter device liberty beyond matrix satisfy metal essence//1/0/3"
Address: 5FpnSswqc97MScQ8cvEjXcT13kNBuNArJKFCxUU6SqeYoBrN

1 Like

Un premier jet, je tente le mode wiki du forum, plus facile à modifier collaborativement avant publication sur gitlab.

Sachant qu’il n’y a plus de « monnaie rendu » ni de « change » dans substrate, je pense qu’il faut retirer leur mention de la RFC.

Oui, et d’ailleurs la notion de semi-opaque n’a plus de sens dans un système sans UTXO, il reste possible de faire du opaque directement, à condition qu’on ajoute la fonctionnalité “oneshot accounts”, je viens de créer une issue sur duniter-v2s pour ça: Oneshot accounts (#44) · Issues · nodes / rust / Duniter v2S · GitLab

Ok donc dans ce cas inutile de le prévoir dans le protocole.
On peut passer sur du modulo 2 ?

Pair transparent, impair one-shot, plus simple.


edit: J’ai mis à jour le poste en ce sens.
Je n’ai juste pas touché au détail des dérivations opaques car j’ai du mal à voir ce que ça implique de ne plus avoir besoin de cash back.

2 Likes

J’ai aussi dans l’idée que le « paiement à soi-même » n’a plus lieu d’être.

Du coup, si on n’a qu’un cas de figure sur les comptes impairs alors la dérivation suivante doit suffire, non ? :

<mnemonic>//<account_id>/i

Si, pour un compte opaque il reste pertinent pour se verser le reste.

Réflexion du moment: Réserver la wallet destiné à être membre à la dérivation 0 ne fait pas trop de sens depuis que les actions de créations d’identités ne sont plus à l’initiative de l’owner.

Ca veut dire que n’importe quelle clé publique présenté à un membre peut se faire certifier, si le owner confirme son identité.

Côté client, on peut ignoré les changements d’état de ce statut pour les dérivation != 0, mais ça fait vraiment cosmétique non ?

Il suffit d’importer ce même mnemonic dans un client qui n’a pas cette limitation, pour se faire certifier 3 dérivations.

Qu’en pensez-vous ?

Ça ne fait pas moins sens qu’avant. c’était déjà une limitation appliquée coté wallet uniquement, rien ne change la dessus. La blockchain n’a de toute façon pas connaissance des notions de dérivations.

Coté wallet, il faut interdire la création de compte membre sur une autre dérivation que //0

Le compte membre doit d’abord être créé sur le wallet, qui doit prévenir niveau UX qu’il faut avoir déjà au moins 1 certificateur.
Une fois le compte membre créé localement, il faut vérifier si le 1er certificateur à déjà publié l’identité, et s’il ne l’a pas fait, inviter l’utilisateur à contacter son 1er certificateur.

Tout ça n’à rien de “cosmétique”, ça défini l’expérience utilisateur :slight_smile:

J’ai bien compris le workflow oui.
Mais tu dis ça comme si la création du compte membre était à l’initiative du membre, comme duniter-v1.
Ce n’est plus le cas désormais, la première action est côté certificateur.

Donc très concrètement, sur Gecko je démarre avec ma dérivation 2, je présente son qrcode à mon certificateur, il publie mon identité.
C’est juste là qu’on décide de ne pas afficher la validation côté client, mais rien ne m’empêche de le valider depuis un autre client.

Au final je peux très facilement me retrouver avec des coffre comportant des comptes membres autre que //0, il faut bien que Gecko traite ces cas sinon ça ne va pas.

Non la tu confonds ce qu’il se passe coté blockchain de ce qu’il se passe coté wallet.
Il n’y a aucune raison de reproduire coté wallet uniquement les étapes qui se déroulent en blockchain, ce serait même idiot.
Il y a plein d’étape coté wallet sans interaction avec la blockchain (comme la création d’un compte), mais indispensables pour fournir l’expérience utilisateur qu’on souhaite fournir :slight_smile:

1 Like

S’il utilise Ğecko, il ne pourra pas le faire. Il suffit d’exiger que le qrcode contienne une info supplémentaire indiquant qu’il s’agit d’un compte “type membre”.

Non, tu peux considérer ces comptes comme des simples portefeuilles, ce n’est pas parce qu’ils sont membres en blockchain que tu dois les considérer comme membres.

Si les gens utilisent des wallet qui ne respectent pas les conventions, c’est à leurs risques et périls, ils n’avaient qu’à utiliser les wallet officiellement recommandées.

Non, je comprends bien que niveau UX on doivent d’abords générer son compte membre (//0), puis se faire certifier dessus.
Je dis simplement que rien n’emêche de se faire certifier //2, et qu’il faut bien traiter ce cas dans l’app, sinon on se retrouve avec un portefeuille membre mais traité comme un non membre.

Donc que dans tous les cas, il faut vérifié l’état de l’idty de chaque dérivation présentes dans un coffre.

Edit: Oui c’est pas faux…

Et alors ? En quoi ça poserai problème ?

Je ne comprend toujours pas pourquoi, pour moi tu n’a besoin de vérifier que //0

… Oui pas tant que ça au final, j’avais surtout en tête nos histoires de longueur de code secret variable en fonction de la présence d’un compte membre ou non, mais je ne vais pas garder cette feature, beaucoup trop compliqué à gérer côté UX.

Plus généralement, pour toutes les conventions qui ne peuvent pas être garanties par la blockchain, tu aura toujours des cas possibles qui ne sont pas prévus suite à l’utilisation de wallet modifiés/piratés.

Si tu essaye de gérer tout les cas possibles tu ne va jamais t’en sortir, je te recommande de ne gérer que les cas prévus par les conventions adoptées, en tout cas c’est comme ça que je ferai si je devais développer un wallet :slight_smile:

1 Like

Oui tu as raison.

Bon du coup j’en profite pour dire qu’on peut dès maintenant suivre l’état de l’identité de chaque wallet dans Gecko, confirmer son identité le moment vue, et suivre l’état du status :slight_smile:

Bon par contre pour le moment c’est avec une UX minimal, et c’est « yolo je peux faire ça sur toutes mes dérivations », mais c’est juste pour les débuts de la gdev.

Ca sera dans le prochain build.

2 Likes

Tikka aussi supporte les chemins de dérivation en import, ce n’est pas vraiment le problème.

Le problème c’est que Gecko, en cachant la dérivation, fait croire à l’utilisateur qu’il créé une adresse à partir du mnémonique. Ce qui est faux. Toi tu le sais, Elois aussi je crois, mais personne d’autre si on ne lit pas intensément le forum comme moi. Et même moi qui l’avait lu, j’avais oublié sinon j’aurai compris plus vite. le problème des adresses différentes.

Du coup les utilisateurs qui arrivent dans Tikka tapent ce que Gecko leur a fait croire et obtienne une adresse différente.

Je ne suis pas contre les dérivations, au contraire, et surtout sur mobile, je trouve cela plus sécurisé.
Mais Tikka se veut un client complet (donc on peut faire des comptes root) qui ne cache rien à ses utilisateurs. C’est sa philosophie.

Je sais que c’est difficile d’afficher des choses pas faciles à comprendre pour l’utilisateur, mais cette “incompatibilité” de Tikka et Gecko n’existe que par ignorance d’une action cachée de Gecko.
Et aussi (je vais corriger ça dans l’interface) parce que Tikka ne précise pas qu’il accepte en import des chemins de dérivation.

Le but c’est justement tous l’écosystème Ğ1 soit designé ainsi!
L’utilisateur n’a pas besoin de savoir que c’est //2 si tous les clients Ğ1 démarrent sur //2 comme premier wallet.
Si Tikka tu veut permettre de créer toutes les dérivations c’est très bien, mais faut savoir si on se met d’accords sur:

//0: Compte membre uniquement
//1: Première dérivation opaque
//2: Première dérivation transparente, créé par defaut
root: doit être généré que sur demande

Si on ne se met pas d’accords là dessus, alors je ne peut pas garder ce mécanisme dans Ğecko, et il faut qu’on se mette d’accords sur autre chose.

Mais dans tous les cas, il faut qu’on se mette d’accords sur quelle adresse est considéré comme l’adresse par défaut d’un mnemonic dans l’écosystème Ğ1, root ou une dérivation ?

Si Tikka est orienté grand public pro par exemple, il faut que ce soit cohérent avec Ğecko et le reste.
Si il est orienté utilisateurs avancés uniquement, alors dans ce cas tu peux peut être générer root par defaut et permettre de tous faire dans l’interface par defaut, mais dans ce cas il faut traiter Tikka comme outils pour utilisateurs avancés uniquement, pas pour qu’un commerçant ou un membre lambda l’utilise quotidiennement pour ses actions.


On est d’accord que tu n’affiches pas dans l’interface tous le processus pour passer du mnémonique jusqu’à ton adresse root ?
Que tu utilises tel algo de crypto, tel format, tel prefix 42, ect … ?

Donc tu ne peux pas dire que Tikka “ne cache rien à ses utilisateurs” :slight_smile:

S’arrêter à root au lieu de dériver en //2, c’est juste un choix arbitraire que tu fais, en te calquant sur ce que fait l’extension polkadot.js au lieu de notre RFC.

1 Like

Je pense que c’est illusoire de croire qu’on peut imposer à tous les clients une seule façon de faire.
Surtout si cela n’est pas imposé par le protocole de la blockchain.

Pour Tikka en tout cas, je ne souhaite pas appliquer cette convention pour l’instant.