Author

Topic: Generate coinbase from to send to miner (ckpool source code question) (Read 252 times)

staff
Activity: 3458
Merit: 6793
Just writing some code
1. Transaction ids received from GBT should be reversed byte-wise or used as is to calculate markel ?
Things are only reversed for display to the user. On the protocol level, things are used as provided.

2. Considering the is no transaction so sha256d of coinbase becomes the markel and 2xhash output of coinbase should be used as is in block header or it should flipped byte-wise ?
ex: 2xSha256 of below coinbase
The sha256d of the coinbase will be the merkle root if there are no other transactions.

01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff2c03dc851300043c487b5a0c5a7b47ff0100000000000000066e5175616e740d2f6e5175616e 742e706f6f6c2fffffffff026fe2ab04000000001976a9144ab4b2aa35879fe47e6a16ea783494f 9dcf615b788ac0000000000000000266a24aa21a9ed60af3e8651f28353ad47a0664c3892b67d82 0d3828af0c5dc854fc2e0bec44d200000000

= 5cb15257b783b9a4c12d1425ad80985a9d43ee474019d5026d04a0e80090f32b

So block header should use it as is or it should be flipped ?

0000002062be1e317f0dce1aa3fcf2b3bf9d604e2b20e853a7575ba03e0d0000000000005cb15257b783b9a4c12d1425ad80985a9d43ee474019d5026d04a0e80090f32b898e7b5aaddc001b00000000
As is. This is correct.

3. Submitblock param = block header + (number of transactions + 1 for coinbase) + coinbase + All the transaction data field received from GBT . Is this correct ?
Yes.
newbie
Activity: 18
Merit: 4
Thanks, Below is the request received from pool, so if you check first header above which looks like big endian has previous hash as is.
It is not big endian.

I do not think that this is exactly what your miner received from the pool. I think what you are seeing is based on an internal representation of the data which makes it appear to be different than what it actually is.

So bloc header has previous hash flipped in 32 bit chunk ?
That is what is being displayed, but that is not what it actually has to be in the block header.

But as per documentation it doesn't say so.
Because your miner is displaying that information incorrectly.

prev_hash: da780ff935f3917ed99a7b616cb98ebb3104b3fa000b7acd0000000000000000
The correct block hash is f90f78da7e91f335617b9ad9bb8eb96cfab30431cd7a0b000000000000000000. You will notice that if you byteswap this so that it is actually in big endian, the block hash becomes 0000000000000000000b7acd3104b3fa6cb98ebbd99a7b6135f3917eda780ff9 which is an actual block that you look up on a block explorer or node. Looking up what your miner is displaying in both its original form and byteswapped form results in not being able to find such a block.

Strange, I can confirm its not cgminer.. I connected to ckpool using tcp socket and raw received message has flipped previous hash
as 6daed056abb0d17f362455ec230dd738ca958301001084f40000000000000000
It should be 56d0ae6d7fd1b0abec55243638d70d23018395caf48410000000000000000000

This better should be reviewed with ck I guess on whats going on Smiley
Alright for now I'm ignoring what cgminer/ckpool doing since its making me crazy. I'm able to prepare correct coinbase now and its decodes properly. Thanks to you Smiley

Last questions:

1. Transaction ids received from GBT should be reversed byte-wise or used as is to calculate markel ?
2. Considering the is no transaction so sha256d of coinbase becomes the markel and 2xhash output of coinbase should be used as is in block header or it should flipped byte-wise ?
ex: 2xSha256 of below coinbase

01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff2c03dc851300043c487b5a0c5a7b47ff0100000000000000066e5175616e740d2f6e5175616e 742e706f6f6c2fffffffff026fe2ab04000000001976a9144ab4b2aa35879fe47e6a16ea783494f 9dcf615b788ac0000000000000000266a24aa21a9ed60af3e8651f28353ad47a0664c3892b67d82 0d3828af0c5dc854fc2e0bec44d200000000

= 5cb15257b783b9a4c12d1425ad80985a9d43ee474019d5026d04a0e80090f32b

So block header should use it as is or it should be flipped ?

0000002062be1e317f0dce1aa3fcf2b3bf9d604e2b20e853a7575ba03e0d0000000000005cb15257b783b9a4c12d1425ad80985a9d43ee474019d5026d04a0e80090f32b898e7b5aaddc001b00000000

3. Submitblock param = block header + (number of transactions + 1 for coinbase) + coinbase + All the transaction data field received from GBT . Is this correct ?
staff
Activity: 3458
Merit: 6793
Just writing some code
Thanks, Below is the request received from pool, so if you check first header above which looks like big endian has previous hash as is.
It is not big endian.

I do not think that this is exactly what your miner received from the pool. I think what you are seeing is based on an internal representation of the data which makes it appear to be different than what it actually is.

So bloc header has previous hash flipped in 32 bit chunk ?
That is what is being displayed, but that is not what it actually has to be in the block header.

But as per documentation it doesn't say so.
Because your miner is displaying that information incorrectly.

prev_hash: da780ff935f3917ed99a7b616cb98ebb3104b3fa000b7acd0000000000000000
The correct block hash is f90f78da7e91f335617b9ad9bb8eb96cfab30431cd7a0b000000000000000000. You will notice that if you byteswap this so that it is actually in big endian, the block hash becomes 0000000000000000000b7acd3104b3fa6cb98ebbd99a7b6135f3917eda780ff9 which is an actual block that you look up on a block explorer or node. Looking up what your miner is displaying in both its original form and byteswapped form results in not being able to find such a block.
newbie
Activity: 18
Merit: 4
cgminer log shows stratum header constructed as below
20000000da780ff935f3917ed99a7b616cb98ebb3104b3fa000b7acd0000000000000000854e4bddb4eeb7c1841b651ceb26f4d12116bfcc2c41ed18220fd701571914ba5a6fdbfa176c214 600000000

Look at version, time, difficulty part. Shouldn't it be flipped as big endian ?
No, everything in Bitcoin is serialized as little endian. Actually, this is serialized as big endian, but in kind of a strange way. It seems like it is being printed out with each 4 byte chunk (32 bit integer length) in big endian, which also means that the merkle root and previous block hash fields are messed up. But this is not the actual block header it is hashing.

And at the calculation of midsate its flipping all 4 bytes.. meaning 00000020f90f78da7e91f335617b9ad9bb8eb96cfab30431cd7a0b000000000000000000dd4b4e8 5c1b7eeb41c651b84d1f426ebccbf162118ed412c01d70f22
This is the correct block header. Everything is in little endian as it should be. This is what the block header should look like.

When submitblock is called, what should be sent as block header ?
The second one.

Thanks, Below is the request received from pool, so if you check first header above which looks like big endian has previous hash as is.
So bloc header has previous hash flipped in 32 bit chunk ? But as per documentation it doesn't say so.


merkle 0: a3d18668bdf36123c62d4f514bf73ea4c7aa6fae2e84b5e5a05a9150167fa029
merkle 1: 56d152aca6c6dd57b6e76c57f6372c6c7bc17e3d2a4b60716129f3c14034cd04
merkle 2: 0e87a49ac8f40fcecf8d5401eccf41dbb1a83884d571119ac50e26f0a8e102ed
merkle 3: 3a017f03b73bf13542e19b8c72083ca666fb3ae8411c7f11043c4fd96ef79b8a
merkle 4: ba6a063a2d07b85a01d18e3cf66752a131a92b797e718d1d7643d9eb9e794afe
merkle 5: 3239626b7d311d43005f593a361c560da9ef9cda164a1fd78e5af9cbaa8006a5
merkle 6: b8e581d27c1830817fbc92df080d474ee0294c377a27d65b6fb38c6971297461
merkle 7: 01f51b074a5c7bf4b4848e4eee2933eca04b819c24973f598f667bf78c88ed11
Pool 0 coinbase 01000000010000000000000000000000000000000000000000000000000....
job_id: 59e1661b0002aa39
prev_hash: da780ff935f3917ed99a7b616cb98ebb3104b3fa000b7acd0000000000000000
coinbase1: 0100000001000000000000000000000000000000000000000000000000000000...
coinbase2: 0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff03d0b3...
bbversion: 20000000
nbit: 176c2146
ntime: 5a6fdbfa
staff
Activity: 3458
Merit: 6793
Just writing some code
cgminer log shows stratum header constructed as below
20000000da780ff935f3917ed99a7b616cb98ebb3104b3fa000b7acd0000000000000000854e4bd db4eeb7c1841b651ceb26f4d12116bfcc2c41ed18220fd701571914ba5a6fdbfa176c2146000000 00

Look at version, time, difficulty part. Shouldn't it be flipped as big endian ?
No, everything in Bitcoin is serialized as little endian. Actually, this is serialized as big endian, but in kind of a strange way. It seems like it is being printed out with each 4 byte chunk (32 bit integer length) in big endian, which also means that the merkle root and previous block hash fields are messed up. But this is not the actual block header it is hashing.

And at the calculation of midsate its flipping all 4 bytes.. meaning 00000020f90f78da7e91f335617b9ad9bb8eb96cfab30431cd7a0b000000000000000000dd4b4e8 5c1b7eeb41c651b84d1f426ebccbf162118ed412c01d70f22
This is the correct block header. Everything is in little endian as it should be. This is what the block header should look like.

When submitblock is called, what should be sent as block header ?
The second one.
newbie
Activity: 18
Merit: 4
You are awesome. Thanks for taking time and explain each parts.
I highly suggest that you read Bitcoin.org's documentation on the raw transaction format as that is basically what you are being given by the stratum protocol. All it is giving you is the entire coinbase transaction with some parts missing that the miner needs to fill out. Those are the nonce and extra nonce which are part of the coinbase.

Coinbase1
----------------
Header               |   01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff
This is not a header. This consists of 4 different fields. The first 4 bytes are the transaction version number, the next byte is the number of inputs. The next 32 bytes are the transaction id of the transaction the input spends from. The 4 bytes after that are the index of the output that is being spent. In a coinbase transaction, the previous txid must be all 0's, and the output index must be 0xffffffff.

Length               |   35 (<= this is 53 decimal length counts till signature part Huh )
Yes, that is the length. It is the length of the scriptSig, which in a coinbase transaction, is known as the coinbase.

Height               |   0371bb07
The first byte is a length specifier. The next 3 bytes are the block height. This is pursuant to BIP 34

                  |   ffffffff (<= is this separator between tx in and tx out ?)
No, this is not a separator. It is the sequence number. Every input has a 4 byte sequence number.

end                       |   00000000
That's the transaction lock time, not "end".

Thanks my friend, actually I'm aware of first part of coinbase1, I'm just calling it header because cgminer has it as static variable name sigheader something. I'm now able to construct entire coinbase but it fails to decode. I'll look try read the document in depth and see if I can figure out what I'm doing wrong. On one look everything looks simple to put together But man so many concepts to go wrong Sad  crazy architecture Smiley

For now I'm putting it on side to study, but now caught into something I though I have solved about stratum header.. This should be separate question but just wanted to put short question in case you have pretty simple explanation.

cgminer log shows stratum header constructed as below
20000000da780ff935f3917ed99a7b616cb98ebb3104b3fa000b7acd0000000000000000854e4bd db4eeb7c1841b651ceb26f4d12116bfcc2c41ed18220fd701571914ba5a6fdbfa176c2146000000 00

Look at version, time, difficulty part. Shouldn't it be flipped as big endian ?

And at the calculation of midsate its flipping all 4 bytes.. meaning 00000020f90f78da7e91f335617b9ad9bb8eb96cfab30431cd7a0b000000000000000000dd4b4e8 5c1b7eeb41c651b84d1f426ebccbf162118ed412c01d70f22

When submitblock is called, what should be sent as block header ?
staff
Activity: 3458
Merit: 6793
Just writing some code
You are awesome. Thanks for taking time and explain each parts.
I highly suggest that you read Bitcoin.org's documentation on the raw transaction format as that is basically what you are being given by the stratum protocol. All it is giving you is the entire coinbase transaction with some parts missing that the miner needs to fill out. Those are the nonce and extra nonce which are part of the coinbase.

Coinbase1
----------------
Header               |   01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff
This is not a header. This consists of 4 different fields. The first 4 bytes are the transaction version number, the next byte is the number of inputs. The next 32 bytes are the transaction id of the transaction the input spends from. The 4 bytes after that are the index of the output that is being spent. In a coinbase transaction, the previous txid must be all 0's, and the output index must be 0xffffffff.

Length               |   35 (<= this is 53 decimal length counts till signature part Huh )
Yes, that is the length. It is the length of the scriptSig, which in a coinbase transaction, is known as the coinbase.

Height               |   0371bb07
The first byte is a length specifier. The next 3 bytes are the block height. This is pursuant to BIP 34

                  |   ffffffff (<= is this separator between tx in and tx out ?)
No, this is not a separator. It is the sequence number. Every input has a 4 byte sequence number.

end                       |   00000000
That's the transaction lock time, not "end".
newbie
Activity: 18
Merit: 4
1. In second part of coinbase ckpool has extradata ckpool and signature /solo.ckpool.org/
hex : 0a 636b706f6f6c (this converts to ckpool) 11 2f736f6c6f2e636b706f6f6c2e6f72672f (this converts to /solo.ckpool.org/)

Q: ckpool is 6 bytes, why its length is set to 0a ?
These aren't actually length specifiers but rather just straight unicode text. The coinbase part of a coinbase transaction can contain basically anything it wants (except that it must begin with the block height and be less than 100 bytes) that does not have to conform to any particular serialization rules. So What this really represents is a newline (0a is newline) followed by ckpool and then another unicode separator and then /solo.ckpool.org/

2. If I want to generate all reward into single wallet address (cScriptPubKey), below pseudo code serialized as per protocol for coinbase 2 is correct ?
I think its should be either 0xffffffff or cCoinbaseValue (coinbasevalue is serialized value returned in getblocktemplate response)

var txOut = cExtraData + cSignature + "ffffffff" + cCoinbaseValue + cScriptPubKey + 0.ToString("x8") + cCommitment + cLockout;
No, this is incorrect. This contains more data than should be in a transaction output. What you have is some combination of the input data and the output data. This is actually the second half of the coinbase transaction which includes all of the outputs and part of the input data.

The only things in a transaction output are the value and scriptPubKey. So you should only have cCoinbaseValue and cScriptPubKey.

0337a3954a (<= what value is this?)
This is actually two values.

The 03 specifies the number of outputs. There are 3 outputs. The rest of that is part of the value.

00000000 (<= if above part is reward value, what is this ?)
This is part of the value. It should be combined with the last 4 bytes of the previous value as the full structure is a 64 bit integer. The full thing is 37a3954a00000000. This is the little endian encoding of the value (which is what Bitcoin uses). The value in decimal is 1251320631 satoshis.

17a9144ab4b2aa35879fe47e6a16ea783494f9dcf615b78772ddc0 (I assume this is where the reward goes)
Only part of this is the output script. That is 17a9144ab4b2aa35879fe47e6a16ea783494f9dcf615b787. The 72ddc0 is part of the next thing.

0000000000
This is the part of the last 3 bytes of the previous thing which is the value of the next output. The value of this is 72ddc00000000000 which is 12639602 satoshis.

1976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0 (and 0.5% fee goes here ?)
Only the 1976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac part is the scriptPubKey. This output is for the fee. The last 0 is part of the next thing.

00000000000000
This (with the previous trailing 0) is the value of the last output, which is 0 satoshis (yes that is allowed). You are also missing a 0 which you have included as part of the next thing, but that is actually part of this one.

0266a24aa21a9ed99acb686178a3404d59c5f4521ccebf9cb523a337b0c05abc8d3ec375e39af7f 00000000 (this is witness provided in getbloctemplate with lock)
Excluding the first 0 and the last 4 zero bytes, this is the scriptPubKey of the last output. It is an OP_RETURN output that commits the witness hashes of the block.

The last 4 bytes are the lock time.


You are awesome. Thanks for taking time and explain each parts.

Coinbase1
----------------
Header               |   01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff
Length               |   35 (<= this is 53 decimal length counts till signature part Huh )
Height               |   0371bb07
Flag Length            |   00
Time with length         |   049dbc6f5a
Random with length         |   046fb28d21
Nonce Length            |   0c

Extra Nonce part
----------------
Nonce1               |   00000000
Nonce2               |   0000000000000000

Coinbase 2
----------------
Unicode Text            |   0a
Extra data               |   636b706f6f6c
Signature Length         |   11
Signature               |   2f736f6c6f2e636b706f6f6c2e6f72672f
                  |   ffffffff (<= is this separator between tx in and tx out ?)
Number of transactions      |   03
1251320631 satoshies      |   37a3954a00000000
Pub script key for reward           |   17a9144ab4b2aa35879fe47e6a16ea783494f9dcf615b787
12639602 satoshies         |   72ddc00000000000
Pub script key for fee              |   1976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac
0 reward               |   0000000000000000
Witness commitment         |   266a24aa21a9ed99acb686178a3404d59c5f4521ccebf9cb523a337b0c05abc8d3ec375e39af7f
end                       |   00000000
staff
Activity: 3458
Merit: 6793
Just writing some code
1. In second part of coinbase ckpool has extradata ckpool and signature /solo.ckpool.org/
hex : 0a 636b706f6f6c (this converts to ckpool) 11 2f736f6c6f2e636b706f6f6c2e6f72672f (this converts to /solo.ckpool.org/)

Q: ckpool is 6 bytes, why its length is set to 0a ?
These aren't actually length specifiers but rather just straight unicode text. The coinbase part of a coinbase transaction can contain basically anything it wants (except that it must begin with the block height and be less than 100 bytes) that does not have to conform to any particular serialization rules. So What this really represents is a newline (0a is newline) followed by ckpool and then another unicode separator and then /solo.ckpool.org/

2. If I want to generate all reward into single wallet address (cScriptPubKey), below pseudo code serialized as per protocol for coinbase 2 is correct ?
I think its should be either 0xffffffff or cCoinbaseValue (coinbasevalue is serialized value returned in getblocktemplate response)

var txOut = cExtraData + cSignature + "ffffffff" + cCoinbaseValue + cScriptPubKey + 0.ToString("x8") + cCommitment + cLockout;
No, this is incorrect. This contains more data than should be in a transaction output. What you have is some combination of the input data and the output data. This is actually the second half of the coinbase transaction which includes all of the outputs and part of the input data.

The only things in a transaction output are the value and scriptPubKey. So you should only have cCoinbaseValue and cScriptPubKey.

0337a3954a (<= what value is this?)
This is actually two values.

The 03 specifies the number of outputs. There are 3 outputs. The rest of that is part of the value.

00000000 (<= if above part is reward value, what is this ?)
This is part of the value. It should be combined with the last 4 bytes of the previous value as the full structure is a 64 bit integer. The full thing is 37a3954a00000000. This is the little endian encoding of the value (which is what Bitcoin uses). The value in decimal is 1251320631 satoshis.

17a9144ab4b2aa35879fe47e6a16ea783494f9dcf615b78772ddc0 (I assume this is where the reward goes)
Only part of this is the output script. That is 17a9144ab4b2aa35879fe47e6a16ea783494f9dcf615b787. The 72ddc0 is part of the next thing.

0000000000
This is the part of the last 3 bytes of the previous thing which is the value of the next output. The value of this is 72ddc00000000000 which is 12639602 satoshis.

1976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0 (and 0.5% fee goes here ?)
Only the 1976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac part is the scriptPubKey. This output is for the fee. The last 0 is part of the next thing.

00000000000000
This (with the previous trailing 0) is the value of the last output, which is 0 satoshis (yes that is allowed). You are also missing a 0 which you have included as part of the next thing, but that is actually part of this one.

0266a24aa21a9ed99acb686178a3404d59c5f4521ccebf9cb523a337b0c05abc8d3ec375e39af7f 00000000 (this is witness provided in getbloctemplate with lock)
Excluding the first 0 and the last 4 zero bytes, this is the scriptPubKey of the last output. It is an OP_RETURN output that commits the witness hashes of the block.

The last 4 bytes are the lock time.
newbie
Activity: 18
Merit: 4
I'm trying to understand how coinbase is generated in ckpool and some part of it I'm not able to figure out

1. In second part of coinbase ckpool has extradata ckpool and signature /solo.ckpool.org/
hex : 0a 636b706f6f6c (this converts to ckpool) 11 2f736f6c6f2e636b706f6f6c2e6f72672f (this converts to /solo.ckpool.org/)

Q: ckpool is 6 bytes, why its length is set to 0a ?

2. If I want to generate all reward into single wallet address (cScriptPubKey), below pseudo code serialized as per protocol for coinbase 2 is correct ?
I think its should be either 0xffffffff or cCoinbaseValue (coinbasevalue is serialized value returned in getblocktemplate response)

var txOut = cExtraData + cSignature + "ffffffff" + cCoinbaseValue + cScriptPubKey + 0.ToString("x8") + cCommitment + cLockout;

3. Below is captured coinbase2 value recieved from solo.ckpool. Can anybody explain parts of it. For some reason I'm not able to understand how 00000000 are in 3 locations

0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff0337a3954a0000000017a 9144ab4b2aa35879fe47e6a16ea783494f9dcf615b78772ddc000000000001976a914f4cbe6c6bb 3a8535c963169c22963d3a20e7686988ac0000000000000000266a24aa21a9ed99acb686178a340 4d59c5f4521ccebf9cb523a337b0c05abc8d3ec375e39af7f00000000

0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff (this part I understand provided with one question above)
0337a3954a (<= what value is this?)
00000000 (<= if above part is reward value, what is this ?)
17a9144ab4b2aa35879fe47e6a16ea783494f9dcf615b78772ddc0 (I assume this is where the reward goes)
0000000000
1976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0 (and 0.5% fee goes here ?)
00000000000000
0266a24aa21a9ed99acb686178a3404d59c5f4521ccebf9cb523a337b0c05abc8d3ec375e39af7f 00000000 (this is witness provided in getbloctemplate with lock)


Jump to: