[1]
Après de longues vacances et après avoir bénéficié de l’aide des gens de Yunohost qui ont finalement résolu les derniers problèmes que j’avais avec ma nouvelle installation, je suis prêt à me concentrer à nouveau sur Duniter.
Il est temps pour moi d’essayer de créer Block zero, le composant nécessaire pour lancer une monnaie Duniter.
https://git.duniter.org/nodes/typescript/duniter/blob/master/doc/Protocol.md
[2]
Ce qui devrait être fait exactement est un mystère pour moi, mais j’espère ralentir la transformation de ce post en tutoriel ou copier/coller dans un tutoriel plus grand.
Ce que je sais jusqu’à présent, c’est que je dois créer le Bloc Zéro manuellement et que le Protocole Duniter contient des informations indirectes mais complètes pour comprendre comment créer un tel bloc.
- Comment le bloc zéro est-il démarré ?
- Dans quel format de fichier est-il écrit ?
- Où devrait-il être situé ?
- Que doit contenir le document ?
Puisqu’il y a une description de ce qu’un “Block document” devrait contenir et beaucoup d’exemples,
Je pense qu’il est prudent de commencer par ça d’abord.
Pour l’instant, j’ai ça:
Version;Type;Currency;Number:PoWMin;Time;MedianTime;UniversalDividend;UnitBase;Issuer;IssuersFrame;IssuersFrameVar;DifferenIssuersCount;PreviousHash;PreviousIssuer;Parameters;MembersCount;Identities;Joiners;Actives;Leaver;Revoked;Excluded;Certifications;Transactions;InnerHash;Nonce;Signature
[3]
J’ai récemment trouvé https://g1.duniter.fr/blockchain/block/0
Il commence à ressembler à ce que je pourrais avoir besoin de nommer le document blockchain.json.
Le bloc ne semble pas correspondre entièrement à l’exemple.
Il n’y a pas de “monetaryMass” ou “len” dans l’exemple.
Beaucoup de mystères subsistent.
Documents - Dois-je d’abord rédiger un document d’identité ?
Hash intérieur - D’où vient le Hash ?
Block_UID - D’où vient le Hash ?
Signatures - D’où vient l’encodage Base64 ?
Deuxième membre - Est-ce nécessaire ? Comment puis-je obtenir la clé publique à partir de cela ?
[4]
J’ai essayé de traquer l’erreur de log qui me dit qu’il ne peut pas trouver le bloc racine, en espérant trouver où j’aurais dû mettre mon fichier json.
[5]
Mais on dirait qu’il essaie d’extraire une base de données sqlite. Je suppose que je dois remplir manuellement la base de données des duniter.
[6]
J’avance quelque part…
admin@Gildurklaus:/var/lib/duniter/.config/duniter/duniter_default$ sudo sqlite3 duniter.db
SQLite version 3.8.7.1 2014-10-29 13:59:56
Enter ".help" for usage hints.
sqlite> .tables
b_index identities_pending sandbox_certs
block idty sandbox_idty
blockchain m_index sandbox_memberships
c_index membership sandbox_txs
cert meta transactions_desc
certifications_pending network transactions_pending
forks peer txs
i_index s_index wallet
[mise-à-jour]
[10]
Pour commencer, au moins deux identités, les membres et les certifications doivent être créés et ensuite le bloc zéro.
Adhésion
Identité
Comment calculer les hashes d’identité:
idty = hashlib.sha256("Version: 10\n" + "Type: Identity\n" + "Currency: guilder-test\n" + "Issuer: 4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR\n" + "UniqueID: folatt\n" + "Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855\n").hexdigest().upper()
>>> idty
'5DA0B40CCABE81DC559CA0A73B025FD047510CF19302028E435EE425D35007B1'
idty = hashlib.sha256("Version: 10\n" + "Type: Identity\n" + "Currency: guilder-test\n" + "Issuer: 4afuUAUANLEY11LZHj7mxtZQxedJ5SMCp2yi9TR1ZMjx\n" + "UniqueID: folat2t\n" + "Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855\n").hexdigest().upper()
>>> idty
'9D821EB140FE97D1C792D519EBDAD1824A80CC72A075F67D8C7144D893046372'
Signature
>>> import hashlib, base64
>>> from ecpy.eddsa import EDDSA
>>> from ecpy.curves import Curve, Point
>>> from ecpy.keys import ECPublicKey, ECPrivateKey
>>> cv = Curve.get_curve('Ed25519')
>>> pu_key = ECPublicKey(Point(0,0,cv))
>>> pv_key = ECPrivateKey(0,cv)
>>> signer = EDDSA(hashlib.sha256)
>>> sig = base64.b64encode(signer.sign(b'01234567890123456789012345678912',pv_key))
>>> sig
'NWRhMGI0MGNjYWJlODFkYzU1OWNhMGE3M2IwMjVmZDA0NzUxMGNmMTkzMDIwMjhlNDM1ZWU0MjVkMzUwMDdiMQ=='
>>>sig = base64.b64encode('9d821eb140fe97d1c792d519ebdad1824a80cc72a075f67d8c7144d893046372')
>>> sig
'OWQ4MjFlYjE0MGZlOTdkMWM3OTJkNTE5ZWJkYWQxODI0YTgwY2M3MmEwNzVmNjdkOGM3MTQ0ZDg5MzA0NjM3Mg=='
Créer des adhésions
INSERT INTO membership VALUES (
"IN", "4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR", 0, 0, "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"folatt", "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "5DA0B40CCABE81DC559CA0A73B025FD047510CF19302028E435EE425D35007B1",
0, NULL, 2000000000, "NWRhMGI0MGNjYWJlODFkYzU1OWNhMGE3M2IwMjVmZDA0NzUxMGNmMTkzMDIwMjhlNDM1ZWU0MjVkMzUwMDdiMQ==", NULL
);
INSERT INTO membership VALUES (
"IN", "4afuUAUANLEY11LZHj7mxtZQxedJ5SMCp2yi9TR1ZMjx", 0, 0, "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"folatt2", "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "9D821EB140FE97D1C792D519EBDAD1824A80CC72A075F67D8C7144D893046372",
0, NULL, 2000000000, "OWQ4MjFlYjE0MGZlOTdkMWM3OTJkNTE5ZWJkYWQxODI0YTgwY2M3MmEwNzVmNjdkOGM3MTQ0ZDg5MzA0NjM3Mg==", NULL
);
[/mise-à-jour]
[7]
J’ai synchronisé mon autre “pico-ordinateur” (de la taille d’un Rpi) avec la devise g1-test.
Je suppose que c’est le type de “document” que je dois insérer.
sqlite> select * from block limit 1;
0|0000DEFA598EA82BC8FF19BC56B49A686E63617DCC7304FAF7F0461FA34E0F9C|2160DC211412C7EF45A7A7E18EE829ABBE0DA86F62F560BAC55ADD90AD61D80E|OQQJ8TVISMgpz8SmdVGHYAUQMDnHpXqeFal4+/q2hV37uyrpC8iF6d50Wgg2TMKhsB/9zelOXZgbuzutAOZ5AA==|g1-test|3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj|
0.0488:86400:1000:86400:100:1051920:12623040:5:1051920:1051920:0.8:6311520:5:24:150:12:0.67:1496527200:1496570400:631152|||10|
7|0||1496842431||0|
1496842431|60|0|300000001565|[]|
["3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:0:YU1rvB9f4mtTr4jyPAMRXs8RJbjHXuPQoT/rXTdMilZ4X4eYVgGcPNa8eU8ewpFBv3UZG+JaZd14143/eyqaBQ==",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:0:jVWEao/AgRazepX84YOYHMDn4RBEn9w5wUXgRCXseO8AXP8cFNejNwNovlmDTEnoDYnBgJzQWuYPWB4ONU2jAQ==",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:0:CyRoNBScGwm/ptCMkjTKH5mxd17h29OJ/1BuOMtYzhoVTVS5W37u0UubOv3/A9ZamnUoaQPNkCMQx2DcURYADw==",
"BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:0:BygPpWD3HVo2fC+4kSsoPUUy7FEj82pWZ5sGOJJhIXoSZy/D+zZR1HkLlvPr7BKACG6n8CtcMqdGDIZUC+rVBA==",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:0:nMRHt7rSyt4Us0nIpmAv3AKF/ab9am44/2/+Vkh6BbPGbqdWQyzfjShrVZPAeT+DA3XZThKL3xtfLwXpkESRBw==",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:0:cLerZVAcol9oJNffKeJelkphstkc+R/gYFAJe/LDd8293uHF8okQ4jBrMB0O0eyq615s6M36l0a4+2xFUyPyCg==",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:0:oJfmvjJI5qi4Tv0gAyrK4b2ypi/8FecH/rfVZRh6wOcTLksOtQVc+d7tA26O+trOy8cKPe6w4umgmjf65GjlCw==",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:0:1L5iHUXEmyNCryg3wNRo7zH04HUMTha0FKsGK07EfnLxay+VlQle9fjjtacU+jBTAA4+kQCspTiqbnxVxoWIBw==",
"BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:0:fdpGZGvfcmSnezGdFOuESJuHvLhwL12GCk5ydjvWYHhqyjmKlL4x/qFvLASIG4/0fDKplMPmwtLE5H7BtAa5AQ==",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:0:CDmBizoPFaeC9JuK1glqXn696ZAupmaxlgx2U2RAkbYk5YaizlPnN8dCtoVq12IF/PS2k0xo7TnJBqoOWS1aBg==",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:0:XGTvcHI15YJj7CmhxytWRvk47bQtWyI0DA+LOahkAhWyBAUtpl8bdbMQHVrh8ZdmZdg4OsWT29alt1kJPb7CCA==",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:0:UDvvUQ7ZGjBgpjN5GzQL2It059EVQVnmytoXDukLo/pVI77TUP3Zi/iARrTHURwoH7/KGDFlOeRQeUpyMSlcAQ==",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:0:lFqh5TBRCqRajAhzv85SAuzgdMlezY7fGr4GJTMG1MOmMDXLOR2moMi9BemR5XtAzAXHAZFjNmwFfk9D1HdHAw==",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:0:UngkGSZbDtx+YVb/Y9GAQA/75rgC2PYexD/to8lYytDLIEASjwMLJtq5z3qfbTTh5al31mLyTsWgDdnR5o90Ag==",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:0:RV7oT77uskZWNkc4iA8atBFvFFtEwl2vekSykZPUzBUeu4LMdp82bNT8Y9zwAmGNjuWofAsXEY65N9Gx3QYQBA==",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:0:udMiCXO4ohn4XdgbLU6LfGjyz+cD3ewyvOHXIxRora8D/LTmiQvrWnag4X057TRK9pydFWiQVsnazcwYLCV7Bg==",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:0:okz2/Q6XnFY8+ze95CxBpcSve6juNDhgPhz9a1OLXIFfM+D/4Cjxi8542+ajZGxYv3BVxOrbc6JCm72mrED5AQ==",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:0:+4OoSFoohLk51qIcBjddLpnXzXSmgasm2L2cp26sLZr7iOZEKy6ukY66orVoFJ839bxAnLFxlxgDJT7XbtwYCA==",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:0:CD61lgzUmE8CxOsE5ps1VhQ4QKs4S2eYFZN5EZW3MnBjM9qvANH9Ok3m3y33f54k2IxALOHus/S2jAfO8gNjCw==",
"4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:0:SN3zed/+WuWAzprLAE95TKhmPMT8UjJ1LPHfjTGQB5uXetNrY4UvGC65jCjKKZn43/lexGTJ4LQPq3C4sBVIAQ==",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:0:RBHzG9gzj8JC0AYxB1L0OBwcMa3jLsXfyXKgSy5bhQOOaPWL5TB40xxnqoI+/+jLlLYkAtXH2axJqzYO9KGJAw==",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:0:5vCp/BQUOAdv00dZM/yrb6CDOH3tjhhCHCxVtwMrZa0p2ufX4kkfdnbDhcDKNz+5zGRwDETJYXrleiNA07ehCQ==",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:0:jWB7RivzLFfTuKDKugZ8xeHV8cP1EcmPoKErohsFUS55crdW7SWAnUeq9TQC6YfaSlnQg7SuqCy4bLUxQpUeBg==",
"BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:0:jIsYFgLLrVZHLO+6LaQUvVJePXDDFP3FLEoqSMA9kKLnrNnkpAjurFMS762RGb0vwX7+MBz/Z9CJy82olZsZCw==",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:0:Mjrc51jluTWKz1NCRqApkvMmd4mYW/gBQWKI3CggC15GtV2xlXdt/psnKapfVemj1g3K1gAxLUkG7bhN6/bLAQ==",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:0:XA9O3rRRMzfmg28GDc6Alu+MV8i1ZEEryNgLYMhRq46BZBFcGnAlbL60tGJSdvWbAkZD1Tf14PZoheTdquBwBQ==",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:0:5QbkZkVpq1Jbb0obfFiSr1P5iVE94NXNDFb1onxO9/CA2Yf8j1ZsOz8quACnZxKWsSnWPCr/jrJMdiGA7JF1Dw==",
"BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:0:LLHrkKavB4LqMRpbr8iKeNb5/Za6VYqU2zRk9DBPyvHR9XEqweRoqojncp//EFwH5NyDR83KZiQ3gITbRKaaAQ==",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:0:8n4Rn9AziOctRBaEr4l63sdF17sB3vcEnrkC2izCTKfde6ZUBW0Oc/SI8+i+hExnpkFSMnWVWiZ6yrnzY3N7AQ==",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:0:IBlYlf6k5uqHgz5QVfzExYJmECLhE+60DOkA01g4KuzPQsHzht+Kjhy6scQYaBSmzdpMy611345AjqwiObKEAg==",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:0:p9J+qXpN8PYWTGxIkaut0PWYhWv5mPKQi3GE0emAHYIXgfOH+sTX2koM5GkNC15NYfR+KOFYq6+96tG4f5NvDw==",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:0:5SIIGYaP9GCuX2e0RYGJ6F0dos38OSGKtbcKxpOz4rM+la9Eqo/nAiBay3vkrScA+oVtXOnLy6nuw9YQNZ77CQ==",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:0:c52+PIFLGryZ4HmHZFALpRl/Rt1A0+MreRzdhk9Z5wbIwNscq4qeJnYSqdxown1A+ZrzB7D2a/MEnIv9J4h+CA==",
"4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:0:ZgHz02YKi6/gGWBRWQNaJRTC6T0mEJIVK6t0Qih63RHf0rr+1LMeyrzsXlvH/qPYGCXshkkRiZ3cjHDRmsxjDg==",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:0:X/rkz3v1ji6znISksiGNnlGmDMx0PUBPbtTaHZo8tbwUsYS3ir3x9/rgBXzBJ0yrZ6SE2oBtnbFESl32djx3Bw=="]|
["BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:hSlooM7BhJ5IKP8lJufFBWS7Ehy+qPCil/1Q+uGwkf/1EX9E6f9xrXscP/dNui4XeMF35X5TX8+TEeL87bFbAQ==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:Galuel",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:VWyuE4Cattjz1JIuQb/7I3E7SeQXu2H+14r9LsgUkpxVELhvgDY8jfBIjfAArJ3Swru/G0wT3XWJS6XP0LntDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:Paulart",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:mmQW40vZNHVLLzJ9lJKTQpTstQSa54X7SpRi5ORSIERyCjZkYF8KN/M5Wg6pYIlX832phKHVg766DNy0HxwuDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cgeek",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:QqyKTfLBRe+Eu4Qcc+oUNbcDmokAbU7U/z8Sy9JoP0YwzyOKo0WR95+niWX1mQg0ElpWgoiwFfnFOJKwRSp9Bg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cuckooland",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:HFmZy01XSXSSsqRWYKR+nIsaReBruJUqYHqJh3EtdRkHV3i30S2lM32pM2w4GHYXNIiOf4+NXzcmuEQVkewBAA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois",
"4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:DMjWT2nhe6WzYI9RUlTu315trqe7vizaDpuTzS/iqsI0S17GT7xkthN+NooqtHMCDSSMAX7ZSCAcyEV0/aimAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:gerard94",
"5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:Nupc7USWqhF14mij7dZkWRf9+EparqERIB5TlqhCUigvOBRRJdyHFQSF0RWuOqQ4M+ufkSdxPx4GQiy2PWoVAA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:kimamila"]|
["5ocqzyDMMWf1V8bsoNhWb1iNwax1e9M7VTUN6navs8of:RH+aBL2YP7g90G/ujN0ww1LXc+QiHGok6/CIlrQ3WWSE1rrWQhYIw4Fas+T56kxPvC3b6PDy8RBWt74TTTTqAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:kimamila",
"7KL2QXXFULDpsQY4UdSr5oEVx6rFE6oxeagRdkCX35bf:e2ZeMPDWG6YahtrwFD+TBtThm/d0GlXOvKFzFRRhIAEa8TIWmYipqM5szM7aLUS5b2IKiFFGMwo9m1JUFuZZDA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cuckooland",
"BfkVa967WrC8YTHPN9tr49Bht8HLHv4wQMR8yu6Yk1iV:ALgSvDa6pnoU8RSKrWEVtBy73DySKzwpYkLSUeiX1+Cs6Uho4HrMD/LXJWHrN3kon+TE+7sXmz2cjm8o8sZ8Cw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:Galuel",
"D7CYHJXjaH4j7zRdWngUbsURPnSnjsCYtvo6f8dvW3C:pJGEABRTTf/zEUliqikPiTuptLN9W31MFBgdYzwiuBYGl353JEYkGvr14bR7pPJVbxyABnk9lfzKzCgwAdLCBw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:elois",
"4Z7Mj7yg98CaJJ1aTjDDQoSgXwMGZvS1dBpN5TRJjTyc:inVtyGm9xeAbE0yRmtyhu+BtKQoh5vp1/M+QjO4WCoUr8HOUkhpYVvve1zRMrJjoYia4VRfr/rD9Y3PwOc/0Cw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:gerard94",
"3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:VbntZ9ZMuHAXNZNBQYQ+hE667AImxjLkRSrIV3IePORGKSo707+H0tAF/FHWJi8jpzir40jK8pGQZ2q0476ADg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cgeek",
"F9m6KBE9qeNqL6rjQrWxbk9y7GwTuAzwvx6CUnczkFYR:4Ypm5yUOlfQgBy8LqnFy8SMTJ4o+ahZDp513zK2DnRqf83fXF96Qfm4bh2AMm9x+coV1RkxNeGzSqYX5SUPwBw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:Paulart"]
|[]|[]|
[]|[]|||1|
0|0|49
sqlite> PRAGMA table_info(block);
0|fork|BOOLEAN|1||0
...
[8]
Premier essai
sqlite> INSERT INTO block VALUES (0, NULL, NULL, NULL, "guilder-test", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
Error: NOT NULL constraint failed: block.hash
[9]
première tentative réussie
sqlite> INSERT INTO block VALUES (0, "", "", "", "guilder-test", "", NULL, NULL, NULL, 10, 2, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
Baser le document sur les informations d’enregistrement sql, c’est ce que j’ai :
# 0 - Je ne suis pas sûr de ce que c'est, mais je suppose que c'est faux.
0|fork|BOOLEAN|1||0
# Blockhash ? Hash de InnerHash:SIGNATURE? Qu'y a-t-il entre les deux?
1|hash|VARCHAR(64)|1||2
# La valeur de hash de Version:Type:Currency:Number:PoWMin:Time:MedianTime:UD:UnitBase:Issuer:IssuersFrame:
# IssuersFrameVar:DifferentIssuersCount:Parameters:MembersCount:Identities:Joiners:actives:Leavers:revoked:Excluded:Transactions
2|inner_hash|VARCHAR(64)|1||0
# Hash: à Nonce: NONCE\n, où la clé publique associée est le champ Émetteur du bloc.
3|signature|VARCHAR(100)|1||0
# "guilder-test" - Nom de la cryptomonnaie
4|currency|VARCHAR(50)|1||0
# "4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR" - Clé publique de keyring.yml
5|issuer|VARCHAR(50)|1||0
# paramètres de cryptomonnaie, Protocol.md#protocol-parameters "0.000054218:86400:100:0:300000:604800:604800:0.9:35136000:3:20:960:10:0.6666666666666666:1489675722:1489675722:2629800"
6|parameters|VARCHAR(255)|0||0
# NULL - Hash du bloc précédent
7|previousHash|VARCHAR(64)|0||0
# NULL - Issuer du bloc précédent
8|previousIssuer|VARCHAR(50)|0||0
# 10 - En supposant qu'il s'agit de la dernière version stable de master/test/data/blocks.js, bien que l'exemple indique qu'elle devrait être 6.
9|version|INTEGER|1||0
# 1? - En espérant que seulement 2 membres minimum sont nécessaires pour commencer le bloc zéro.
10|membersCount|INTEGER|1||0
# 0? - compteur de masse monétaire?
11|monetaryMass|VARCHAR(100)|0|'0'|0
# NULL - ??
12|UDTime|DATETIME|0||0
# 1523173253? - Une sorte de date de création ?
13|medianTime|DATETIME|1||0
# NULL - Si HEAD.number == 0, HEAD.dividend doit être nul.
14|dividend|INTEGER|0|'0'|0
# 0 - "Pour le bloc racine, UnitBase doit être égal à 0." selon Protocol.md
15|unitbase|INTEGER|0||0
# 1523173253? - Le Time & MedianTime du bloc racine doit être égal.
16|time|DATETIME|1||0
# 0 - Pouvoir de la difficulté de travail ? Je pensais que la génération de monnaie Duniter était basée sur le temps.
17|powMin|INTEGER|1||0
# 0 - Numéro de bloc #0
18|number|INTEGER|1||1
# 0 - ??
19|nonce|INTEGER|1||0
# [] - Vide pour le bloc #0
20|transactions|TEXT|0||0
# ["4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR:??:0:??",
"??:4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR:0:??"] # issuer#1:issuer#2:id of block#0: Some kind of Base64 encoding.
21|certifications|TEXT|0||0
# ["4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR:?Issuer#2?:
0-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:folatt",
"4afuUAUANLEY11LZHj7mxtZQxedJ5SMCp2yi9TR1ZMjx:4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR:
0-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:folatt2"] - issuer#1:issuer#2:hashlib.sha256('').hexdigest():username.
22|identities|TEXT|0||0
# ["4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR:?Issuer#2?:
0-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:
0-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:folatt",
"4afuUAUANLEY11LZHj7mxtZQxedJ5SMCp2yi9TR1ZMjx:4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR:
0-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:
0-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855:folatt2"] - issuer#1:issuer#2:hashlib.sha256('').hexdigest():username.
23|joiners|TEXT|0||0
# [] - Vide pour le bloc #0
24|actives|TEXT|0||0
# [] - Vide pour le bloc #0
25|leavers|TEXT|0||0
# [] - Vide pour le bloc #0
26|revoked|TEXT|0||0
# [] - Vide pour le bloc #0
27|excluded|TEXT|0||0
# NULL - ??
28|created|DATETIME|0|NULL|0
# NULL - ??
29|updated|DATETIME|0|NULL|0
# 1 - ??
30|issuersFrame|INTEGER|0||0
# 0 - ??
31|issuersFrameVar|INTEGER|0||0
# 0 - ??
32|issuersCount|INTEGER|0||0
# 0 - ??
33|len|INTEGER|0||0
De plus, une ou deux adhésions doivent être créées.
# IN - ??
0|membership|CHAR(2)|1||0
# Public key from keyring.yml - "4FE3bGwDNwsjLzAKF7f87NCEnwgKqTipH4tgK8HuXEwR"
1|issuer|VARCHAR(50)|1||1
# 0 - Block Number #0
2|number|INTEGER|1||0
# 0 - Block Number #0
3|blockNumber|INTEGER|0||0
# 0000???? - ??
4|blockHash|VARCHAR(64)|1||0
# folatt - Your username
5|userid|VARCHAR(255)|1||0
# 0-<blockHash> - ??
6|certts|VARCHAR(100)|1||0
# certts - ??
7|block|INTEGER|0||0
# <Another hash> - ??
8|fpr|VARCHAR(64)|0||0
# <Third hash> - ??
9|idtyHash|VARCHAR(64)|0||0
# 0 - ??
10|written|BOOLEAN|1||0
# NULL - ??
11|written_number|INTEGER|0||0
# 1523275270 - ??
12|expires_on|INTEGER|0||0
# <Ed25519 pattern Base64 encoding signature> - ??
13|signature|VARCHAR(50)|0||2
# NULL - ??
14|expired|INTEGER|0||0
Rien ne se passe après avoir ajouté l’enregistrement 0 autre que le fait que je ne vois plus info : Block resolution : 0 potential blocks for root block
apparaissent toutes les heures dans duniter.log.
InnerHash
Innerhash résolu !
>>> innerhash = hashlib.sha256("Version: 10\n" + "Type: Block\n" + "Currency: duniter_unit_test_currency\n" + "Number: 0\n" + "PoWMin: 0\n" + "Time: 1483614905\n" + "MedianTime: 1483614905\n" + "UnitBase: 0\n" + "Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV\n" + "IssuersFrame: 1\n" + "IssuersFrameVar: 0\n" + "DifferentIssuersCount: 0\n" + "Parameters: 0.007376575:3600:120:0:40:604800:31536000:1:604800:604800:0.9:31536000:3:20:960:10:0.6666666666666666:1483614905:1483614905:100\n" + "MembersCount: 2\n" + "Identities:\n" +
"DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:tic\n" + "DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo:lcekuS0eP2dpFL99imJcwvDAwx49diiDMkG8Lj7FLkC/6IJ0tgNjUzCIZgMGi7bL5tODRiWi9B49UMXb8b3MAw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:toc\n" + "Joiners:\n" + "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:tic\n" +
"DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo:80pUx9YBk0RwqrVrQQA+PuxoNn21A8NwQ3824CQPU1ad9R1oDXc/pU6NVpQv92LM8gaWs/Pm1mLXNNVnr+m6BA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:toc\n" +
"Actives:\n" + "Leavers:\n" + "Revoked:\n" + "Excluded:\n" + "Certifications:\n" + "DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo:DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:0:vMaYgBSnU+83AYOVQCZAx1XLpg/F1MmMztDfCnZvl8hPs4LE9tcDvCrrFogAwMEW2N7Y0gCH62/fBMgw4KrGCA==\n" + "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV:DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo:0:RKIGMgYIhB9FmjPbmyo4egPufg/iTpBznYGZp5hjK1WZ1a9imQldLNUMe0eiPlSKJTK/JD3gOlCiynOEY2csBA==\n" + "Transactions:\n").hexdigest().toupper()
>>> innerhash
'7A4E76A9A3410594AC9AED94B14AD9892426D76EDAF735CFE6C66432E422A63F'
J’ai utilisé l’exemple valid_root sur blocks.js pour valider ma réponse.
Je l’ai aussi essayé avec le bloc zéro de g1-test et aussi celui-ci est correct quand les données sont arrêtées comme dans block.js.
[1]
After a long vacation and having had great help from the people of Yunohost that would finally fix the last issues I had with my new installation, I’m ready to focus on Duniter again.
It’s time for my attempt to create Block zero, the necessary component needed to kickstart a Duniter currency.
[2]
What exactly should be done is a mystery to me, but I hope to slowy turning this post into a tutorial or copy/paste it into a larger one.
What I know so far is that I have to create Block Zero manually and that the Duniter Protocol contains indirect but complete information to figure out how to create such a block.
- How is block zero started?
- Which file format is it written in?
- Where should it be located?
- What should the document contain?
Since there’s a description of what a “Block document” should contain and plenty of examples,
I think it’s safe to start with that first.
So far I’ve got this:
[3]
I’ve recently found https://g1.duniter.fr/blockchain/block/0
It’s beginning to look like I might need to name the document blockchain.json.
The block’s doesn’t seem to correspond to the example entirely.
There’s no “monetaryMass” or “len” in the example.
A lot of mysteries remain.
- Documents - Do I need to write an identity document first?
- Inner Hash - Where does the Hash come from?
- Block_UID - Where does the Hash come from?
- Signatures - Where does the Base64 encoding come from?
- Second member - Is it necessary? How would I get the public key from that?
[4]
I tried tracking down the log error that tells me it can’t find the root block, hoping to figure out where I shoud have put my json file.
[5]
But this looks like it’s trying to dig out an sqlite database. I’m guessing that I have to manually fill up the duniter database then.
[6]
I’m getting somewhere.
[7]
I Synched my other “pico-computer” (Rpi-sized) with the g1-test currency.
I guess this is the type of “document” I have to insert.
[8]
First try
[9]
First succesful insert
Basing the document on the sql record info this is what I have: