pools de minage : protocole Stratum : problème d'implémentation en python
Pendant quelques jours, j’essaie d’écrire un script simple en python pour communiquer avec le serveur de pool de strate. J’utilise le code simplifié de NightMiner (https://github.com/ricmoo/nightminer/) et certains testnet que j’ai trouvés ( stratum+tcp://pool.bitcoincloud.net:4008), mais je ne peux pas obtenir le bon résultat. Peut-être que quelqu’un de plus expérimenté pourrait m’aider. Ci-dessous, je montre chaque étape de mon script (étape, pas de code source python).
1. connectez-vous au serveur, autorisez, obtenez les données de travail
Après m’être connecté au serveur, j’envoie ces requêtes :
b'{« id »: 1, « method »: « mining.subscribe », « params »: []}n’
b ‘{« params »: [« testuser », « anything »], « id »: 2, « method »: « mining.authorize »}n’
et obtenez la réponse suivante :
{« id »:1, »résultat »:[[[« mining.set_difficulty », »deadbeefcafebabea200000000000000″],[« mining.notify », »deadbeefcafebabea200000000000000″]], »40000004″,4], »erreur »:null}
{« id »:null, »method »: »mining.set_difficulty », »params »:[0.01]}
{« id »:null, »method »: »mining.notify », »params »:[« E4C » »4128bf630f57387b00e25b419d1bb77e667e4036a7d8fee80000015600000000″ »01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2503a77614048c8a145e08″ »122f626974636f696e636c6f75642e6e65742f0000000002062c9c04000000001976a91423e020eacd64acfe093150331d44fdbcc0c7ce0688acc2eb0b00000000001976a91400bf6d61c2a34df5a9ea338fcad188c31bb4a52388ac00000000″[« 4ca » »4128bf630f57387b00e25b419d1bb77e667e4036a7d8fee80000015600000000″ »01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2503a77614048c8a145e08″ »122f626974636f696e636c6f75642e6e65742f0000000002062c9c04000000001976a91423e020eacd64acfe093150331d44fdbcc0c7ce0688acc2eb0b00000000001976a91400bf6d61c2a34df5a9ea338fcad188c31bb4a52388ac00000000″[], »20000000″, »1a02b098″, »5e148a8c »,vrai]}
2. obtenez la base de données et la racine de merkle
Avec ces données et extranounce = ‘00000000’, je peux construire la coinbase (sous forme d’octet, mais je montrerai en hexadécimal dans cet exemple):
coinbase=coinb1+extranounce1+extranounce2+coinb2
coinbase = b’01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2503a77614048c8a145e084000000400000000122f626974636f696e636c6f75642e6e65742f0000000002062c9c04000000001976a91423e020eacd64acfe093150331d44fdbcc0c7ce0688acc2eb0b00000000001976a91400bf6d61c2a34df5a9ea338fcad188c31bb4a52388ac00000000′
La prochaine chose à faire est de double hacher la coinbase avec l’algo SHA256, ce qui donne les octets suivants:
b’9b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a23′
Il n’y a pas de branches merkle (le tableau des branches merkle est vide), donc le hachage ci-dessus est notre racine merkle.
3. construire l’en-tête
Avec la racine merkle et les données reçues à l’étape 1, je peux commencer à créer un en-tête :
header= version + prevhash + merkle root + ntime + nbits + nonce
J’utilise les valeurs comme suit :
version – reçu ‘20000000’, après conversion little-endian c’est ‘00000020’
prevhash – reçu ‘4128bf630f57387b00e25b419d1bb77e667e4036a7d8fee80000015600000000′, après la conversion, il est ’63bf28417b38570f415be2007eb71b9d36407e66e8fed8a75601000000000000’ (ordre inverse 4 octets)
racine merkle – obtenez ‘9b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a23’ à l’étape 2, reste ainsi
ntime – reçu ‘5e148a8c’, après conversion c’est ‘8c8a145e’
nbits – reçu ‘1a02b098′, après conversion c’est ’98b0021a’
L’en-tête est donc
b’0000002063bf28417b38570f415be2007eb71b9d36407e66e8fed8a756010000000000009b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a238c8ad4444f9303081a238c800a145e
4. rechercher nonce
la difficulté est de 0,01, donc mon objectif est
00000063ff9c00000000000000000000000000000000000000000000000000000000
après quelques calculs, je trouve ces 4 octets pour l’utiliser comme nonce :
b’d0cf1040′
donc mon en-tête complet est maintenant
b’0000002063bf28417b38570f415be2007eb71b9d36407e66e8fed8a756010000000000009b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a0238c8a21a145a8ad4444f9303081a0238c8a145a145e
après le double hachage avec l’algo SHA256 et l’ordre des octets inversés, j’obtiens ce hachage :
000000032f201567fc4d02fa468bf2dc6a5c21ae70098c124e99ee7d2520ca26
qui est en dessous de ma cible, donc ‘d0cf1040’ devrait être le bon nonce.
5. soumettre une annonce
la dernière chose à faire est de soumettre les résultats, j’envoie donc cette requête au serveur :
b'{« id »:2, « method »: »mining.submit », »params »:[« testuser », »4ca », »00000000″, »5e148a8c », »d0cf1040″]}n’
et voici la réponse que j’obtiens :
{« id »:2, »result »:false, »error »:null}
Je n’ai aucune idée de pourquoi j’obtiens result = false. Je ne peux que supposer qu’il y a une erreur à l’étape 3 (en-tête de construction) et que cette erreur est liée à l’ordre des octets de certaines valeurs, mais je ne trouve pas cette erreur (j’ai essayé de nombreuses variantes de l’ordre des octets, mais je n’obtiens jamais le résultat de la réponse = vrai).
Je serai très obligé si quelqu’un peut vérifier ces calculs et me donner quelques conseils.