2025.01.09
nonce가 자동으로 증가하도록 코드를 수정하다 보니 이제까지 의 예제 string이 뭔가 잘못되어 있다.
모든 정보가 string으로 된다고 했는데 다시 정리해서 보니 말이 안된다.
일단 다시 정리
해더는 4+32+32+4+4+4 => 80byte (640bit)
Hash가 00000000000000000024fb37364cbf81fd49cc2d51c09c75c35433c3a1945d04 인데
스트링으로 그대로 입력하면 64 char 되므로 32byte가 아니다.
보이는 것만 hex format
https://www.blockchain.com/explorer/blocks/btc/500000
#500000 자료로 다시 테스트
Version 0x20000000
Preve(#499999) 0000000000000000007962066dcd6675830883516bcf40047d42740a85eb2919
Merkle Root 31951c69428a95a46b517ffb0de12fec1bd0b2392aec07b64573e03ded31621f
Mined on 2017년 12월 19일 오전 3:35:25
Hash 00000000000000000024fb37364cbf81fd49cc2d51c09c75c35433c3a1945d04
날짜를 숫자로 바꾸는 곳은 여기
https://www.epochconverter.com/
Epoch Converter
Convert Unix Timestamps (and many other date formats) to regular dates.
www.epochconverter.com
Epoch timestamp : 1513654525 Timestamp in milliseconds: 1513654525000 Date and time (GMT) : 2017년 December 19일 Tuesday AM 3:35:25 Date and time (your time zone): 2017년 12월 19일 화요일 오후 12:35:25 GMT+09:00
서버에서 보여주는 것이 Local 기준이라면
Epoch timestamp : 1513622125 Timestamp in milliseconds: 1513622125000 Date and time (GMT): 2017년 December 18일 Monday PM 6:35:25 Date and time (your time zone) : 2017년 12월 19일 화요일 오전 3:35:25 GMT+09:00
이제 여기에 MSB/LSB 문제가
2025.01.10
영어로 비트코인 헤더 예제 구글링
https://developer.bitcoin.org/reference/block_chain.html
Block Chain — Bitcoin
This site aims to provide the docs you need to understand Bitcoin and start building Bitcoin-based applications.
developer.bitcoin.org
An example header in hex:
02000000 ........................... Block version: 2
b6ff0b1b1680a2862a30ca44d346d9e8
910d334beb48ca0c0000000000000000 ... Hash of previous block's header
9d10aa52ee949386ca9385695f04ede2
70dda20810decd12bc9b048aaab31471 ... Merkle root
24d95a54 ........................... [Unix time][unix epoch time]: 1415239972
30c31b18 ........................... Target: 0x1bc330 * 256**(0x18-3)
fe9f0864 ........................... Nonce
L->M 이면 멤버의 순서도 바꿔야 될 것 같다.
Web SHA256에 넣기위해 bit/little edian 코드를 물어봤다.
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <string>
// 헥스 문자열을 바이트 배열로 변환하는 함수
std::string hexToBytes(const std::string& hex) {
std::string bytes;
bytes.reserve(hex.size() / 2);
for (std::size_t i = 0; i < hex.size(); i += 2) {
unsigned byte;
std::istringstream hexByte(hex.substr(i, 2));
hexByte >> std::hex >> byte;
bytes.push_back(static_cast<char>(byte));
}
return bytes;
}
// 바이트 배열을 big endian으로 변환하는 함수
std::string toBigEndian(std::string& bytes) {
std::reverse(bytes.begin(), bytes.end());
return bytes;
}
// 바이트 배열을 헥스 문자열로 변환하는 함수
std::string bytesToHex(const std::string& bytes) {
std::ostringstream hex;
for (unsigned char byte : bytes) {
hex << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
}
return hex.str();
}
int main() {
std::string hexString = "0a1b2c3d";
std::string bytes = hexToBytes(hexString);
std::string bigEndianBytes = toBigEndian(bytes);
std::string bigEndianHexString = bytesToHex(bigEndianBytes);
std::cout << "Original Hex String: " << hexString << std::endl;
std::cout << "Big Endian Hex String: " << bigEndianHexString << std::endl;
return 0;
}
구글링 하다가 제대로 된 정보를 찾았다.
https://jusths.tistory.com/48
SHA-256 Bitcoin
SHA-256 씨리이즈 1. SHA-256 Hash Algorithm 2. SHA-256 프로세스 정리 3. SHA-256 By Hand - Message Expansion Function 4. SHA-256 By Hand - Round Function 5. SHA-256 Bitcoin - 참고링크: http://www.righto.com/2014/09/mining-bitcoin-with-pencil-an
jusths.tistory.com
Little Endian & Double SHA256 이 핵심
Double SHA256 = SHA256(SHA256(Header))
파트
Little Endian 으로 만들기 → 바이트 순서 반대로
version
0x01000000
previous block hash
0x bddd99ccfda39da1b108ce1a5d70038d0a967bacb68b6b63065f626a00000000
merkle root
0x44f672226090d85db9a9f2fbfe5f0f9609b387af7be5b7fbb7a1767c831c9e99
time
0x 5dbe6649
difficulty bits
0xffff001d
nonce
0x05e0ed6d
위 값들로 계산될 해시값
0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449
- https://www.unixtimestamp.com/
Unix Time Stamp - Epoch Converter
Epoch and unix timestamp converter for developers. Date and time function syntax reference for various programming languages.
www.unixtimestamp.com
위의 영문 싸이트에서의 예제도 테스트
02000000b6ff0b1b1680a2862a30ca44d346d9e8910d334beb48ca0c00000000000000009d10aa52ee949386ca9385695f04ede270dda20810decd12bc9b048aaab3147124d95a5430c31b18fe9f0864
=>
2837af674e81436b09e0c937e94d96fe32e5c872391ba1090000000000000000
2025.01.11
80Byte SHA256, 32Byte SHA256
//------------------------------------------------------------------------------
//First Stage
//------------------------------------------------------------------------------
for (int j=0; j<8; j++) {
data_in[j] = SHA256_H0[j];
}
for (int j = 0; j < 64; j++) {
imessage[j] = message[j];
}
for (int j = 0; j < 16; j++) {
msg[j] = imessage[j*4+0] << 24 |
imessage[j*4+1] << 16 |
imessage[j*4+2] << 8 |
imessage[j*4+3] ;
}
printf("----------------------------------------\n");
printf("Message\n");
for (int j=0; j<16; j++) {
printf("%08x ", msg[j]);
printf("\n");
}
sha256_core(msg, data_in, data_tmp);
//------------------------------------------------------------------------------
//Second (80-64 byte)
//------------------------------------------------------------------------------
for (int j = 0; j < 64; j++) {
if (j<16) imessage[j] = message[j+64];
else imessage[j] = 0;
}
imessage[16] = 0x80;
UINT len_bits = 80*8;
imessage[64-4] = (len_bit >> 8*3) & 0xff;
imessage[64-3] = (len_bit >> 8*2) & 0xff;
imessage[64-2] = (len_bit >> 8*1) & 0xff;
imessage[64-1] = (len_bit >> 8*0) & 0xff;
for (int j = 0; j < 16; j++) {
msg[j] = imessage[j*4+0] << 24 |
imessage[j*4+1] << 16 |
imessage[j*4+2] << 8 |
imessage[j*4+3] ;
}
printf("----------------------------------------\n");
printf("Message\n");
for (int j=0; j<16; j++) {
printf("%08x ", msg[j]);
printf("\n");
}
sha256_core(msg, data_tmp, hash_first);
//------------------------------------------------------------------------------
//Double
//------------------------------------------------------------------------------
for (int j=0; j<8; j++) {
data_in[j] = SHA256_H0[j];
}
for (int j = 0; j < 16; j++) {
if (j<8) msg[j] = hash_first[j];
else msg[j] = 0;
}
msg[8] = 0x80000000;
msg[15] = 32*8;
printf("----------------------------------------\n");
printf("Message\n");
for (int j=0; j<16; j++) {
printf("%08x ", msg[j]);
printf("\n");
}
sha256_core(msg, data_in, hash_second);
첫 SHA256은 80byte 이므로 2단계로 변환
두번째 SHA256은 첫번째 hash를 다시 변환 하므로 32 Byte 입력