Monday, July 1, 2024

mining swimming pools – Stratum protocol – drawback with implementation in python

For a few days I am attempting to write down easy script in python to speak with stratum pool server. I am utilizing simplified code of NightMiner (https://github.com/ricmoo/nightminer/) and a few testnet I’ve foud ( stratum+tcp://pool.bitcoincloud.internet:4008), however I am unable to get the correct end result. Possibly somebody extra skilled might assist me. Beneath I present every step of my script (step, no python supply code).

1. hook up with the server, authorize, get the job knowledge

After connecting to the server I ship this requests:

b'{"id": 1, "methodology": "mining.subscribe", "params": []}n'
b'{"params": ["testuser", "anything"], "id": 2, "methodology": "mining.authorize"}n'

and get the next response:

{"id":1,"end result":[[["mining.set_difficulty","deadbeefcafebabea200000000000000"],["mining.notify","deadbeefcafebabea200000000000000"]],"40000004",4],"error":null}
{"id":null,"methodology":"mining.set_difficulty","params":[0.01]}
{"id":null,"methodology":"mining.notify","params":["4ca","4128bf630f57387b00e25b419d1bb77e667e4036a7d8fee80000015600000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2503a77614048c8a145e08","122f626974636f696e636c6f75642e6e65742f0000000002062c9c04000000001976a91423e020eacd64acfe093150331d44fdbcc0c7ce0688acc2eb0b00000000001976a91400bf6d61c2a34df5a9ea338fcad188c31bb4a52388ac00000000",[],"20000000","1a02b098","5e148a8c",true]}

2. get the coinbase and merkle root

With this knowledge and extranounce=”00000000″ I can construct the coinbase (in byte type, however I’ll present as hex on this instance):

coinbase=coinb1+extranounce1+extranounce2+coinb2
coinbase=b'01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2503a77614048c8a145e084000000400000000122f626974636f696e636c6f75642e6e65742f0000000002062c9c04000000001976a91423e020eacd64acfe093150331d44fdbcc0c7ce0688acc2eb0b00000000001976a91400bf6d61c2a34df5a9ea338fcad188c31bb4a52388ac00000000'

Subsequent factor to do is double hash the coinbase with SHA256 algo, which supplies as the next bytes:

b'9b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a23'

There isn’t any merkle branches (merkle branches array is empty), so hash above is our merkle root.

3. constructing the header

With merkle root and knowledge obtained in step 1, I can begin constructing a header:

header= model + prevhash + merkle root + ntime + nbits + nonce

I exploit the values as follows:

model - obtained '20000000', after little-endian conversion it's '00000020'
prevhash - obtained '4128bf630f57387b00e25b419d1bb77e667e4036a7d8fee80000015600000000', after conversion it's '63bf28417b38570f415be2007eb71b9d36407e66e8fed8a75601000000000000' (reverse bytes order each 4 bytes)
merkle root - get '9b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a23' in step 2, stays that means
ntime - obtained '5e148a8c', after conversion it's '8c8a145e'
nbits - obtained '1a02b098', after conversion it's '98b0021a'

So the header is

b'0000002063bf28417b38570f415be2007eb71b9d36407e66e8fed8a756010000000000009b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a238c8a145e98b0021a' + nonce

4. search nonce

the issue is 0.01, so my goal is

00000063ff9c0000000000000000000000000000000000000000000000000000

after some calculations, I discover this 4 bytes to make use of it as a nonce:

b'd0cf1040'

so my full header is now

b'0000002063bf28417b38570f415be2007eb71b9d36407e66e8fed8a756010000000000009b9c9ab0b1c92844e4fed3f895f9443fefcda5ae02cc5a8ad4444f9303081a238c8a145e98b0021ad0cf1040'

after double-hashing it with SHA256 algo and reverse bytes order I get this hash:

000000032f201567fc4d02fa468bf2dc6a5c21ae70098c124e99ee7d2520ca26

which is beneath my goal, so ‘d0cf1040’ needs to be the right nonce.

5. submit nounce

very last thing to do is submitting the outcomes, so I ship this request to the server:

b'{"id":2, "methodology":"mining.submit","params":["testuser","4ca","00000000","5e148a8c","d0cf1040"]}n'

and that is response I get:

{"id":2,"end result":false,"error":null}

I do not know why I get end result=false. I can solely suppose there’s a mistake in step 3 (constructing header) and this error is expounded to byte-order of some values, however I am unable to discover this error (I’ve tried many variants of byte-order, however by no means get the response end result=true).

I will likely be a lot obliged if anybody can verify this calculations and provides me some ideas.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles