Fix for address calculation
This commit is contained in:
parent
853eec6038
commit
9284358def
@ -2,9 +2,13 @@ cmake_minimum_required(VERSION 3.19)
|
|||||||
project(btcexplorer)
|
project(btcexplorer)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fconcepts-diagnostics-depth=2")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
|
|
||||||
include_directories(OPENSSL_INCLUDE_DIR)
|
include_directories(OPENSSL_INCLUDE_DIR)
|
||||||
|
|||||||
@ -32,6 +32,10 @@ Script::Script(std::span<uint8_t> data, bool coinbase) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScriptType Script::type() const {
|
ScriptType Script::type() const {
|
||||||
|
if(_operations.size() < 2) {
|
||||||
|
return ScriptType::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
if(_operations[0].opCode <= OpCode::OP_PUSHDATA4 && _operations[1].opCode == OpCode::OP_CHECKSIG) {
|
if(_operations[0].opCode <= OpCode::OP_PUSHDATA4 && _operations[1].opCode == OpCode::OP_CHECKSIG) {
|
||||||
return ScriptType::P2PK;
|
return ScriptType::P2PK;
|
||||||
} else if(_operations[0].opCode == OpCode::OP_DUP
|
} else if(_operations[0].opCode == OpCode::OP_DUP
|
||||||
@ -42,21 +46,19 @@ ScriptType Script::type() const {
|
|||||||
{
|
{
|
||||||
return ScriptType::P2PKH;
|
return ScriptType::P2PKH;
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Unsupported script type");
|
return ScriptType::Unknown;
|
||||||
|
//throw std::runtime_error("Unsupported script type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Script::address() {
|
std::string Script::address() {
|
||||||
auto pubKey = publicKey();
|
auto pubKey = publicKey();
|
||||||
if(!pubKey.empty()) {
|
if(!pubKey.empty()) {
|
||||||
auto hash160 = hash::hash160(pubKey);
|
auto hash160 = hash::hash160(pubKey, 0); // TODO: this value should depend on BlockMagic
|
||||||
std::array<uint8_t, RIPEMD160_DIGEST_LENGTH + 1> prefixedHash{};
|
auto secondHash = hash::hash256(hash160);
|
||||||
prefixedHash[0] = 0; // TODO: this value should depend on BlockMagic
|
|
||||||
std::copy_n(hash160.begin(), hash160.size(), prefixedHash.begin() + 1);
|
|
||||||
auto secondHash = hash::sha256(prefixedHash);
|
|
||||||
std::array<uint8_t, RIPEMD160_DIGEST_LENGTH + 1 + 4> finalHash{};
|
std::array<uint8_t, RIPEMD160_DIGEST_LENGTH + 1 + 4> finalHash{};
|
||||||
std::copy(prefixedHash.begin(), prefixedHash.end(), finalHash.begin());
|
std::copy(hash160.begin(), hash160.end(), finalHash.begin());
|
||||||
std::copy_n(secondHash.begin(), 4, finalHash.begin() + prefixedHash.size());
|
std::copy_n(secondHash.begin(), 4, finalHash.begin() + hash160.size());
|
||||||
return hash::base58(finalHash);
|
return hash::base58(finalHash);
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
@ -66,6 +68,7 @@ std::string Script::address() {
|
|||||||
std::span<uint8_t> Script::publicKey() {
|
std::span<uint8_t> Script::publicKey() {
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case P2PK: return _operations[0].input;
|
case P2PK: return _operations[0].input;
|
||||||
|
case P2PKH: return _operations[2].input;
|
||||||
default: return {};
|
default: return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ Transaction::Transaction(const std::byte *data) {
|
|||||||
VarInt inputCount(data + sizeof(_version));
|
VarInt inputCount(data + sizeof(_version));
|
||||||
const std::byte* curPtr = data + sizeof(_version) + inputCount.size();
|
const std::byte* curPtr = data + sizeof(_version) + inputCount.size();
|
||||||
|
|
||||||
std::cout << "======== Transaction ========" << std::endl;
|
//std::cout << "======== Transaction ========" << std::endl;
|
||||||
|
|
||||||
for(size_t i = 0; i < inputCount.value(); ++i) {
|
for(size_t i = 0; i < inputCount.value(); ++i) {
|
||||||
TxInput input(curPtr);
|
TxInput input(curPtr);
|
||||||
@ -21,7 +21,7 @@ Transaction::Transaction(const std::byte *data) {
|
|||||||
for(size_t i = 0; i < outputCount.value(); ++i) {
|
for(size_t i = 0; i < outputCount.value(); ++i) {
|
||||||
TxOutput output(curPtr);
|
TxOutput output(curPtr);
|
||||||
curPtr += output.size();
|
curPtr += output.size();
|
||||||
std::cout << "Output " << output.value()/100000000.0 << " BTC to address: " << output.address() << std::endl;
|
//std::cout << "Output " << output.value()/100000000.0 << " BTC to address: " << output.address() << std::endl;
|
||||||
_outputs.emplace_back(std::move(output));
|
_outputs.emplace_back(std::move(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
hash.h
21
hash.h
@ -65,11 +65,32 @@ namespace hash {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<ByteArray T>
|
||||||
|
std::array<uint8_t,RIPEMD160_DIGEST_LENGTH + 1> ripemd160(const T& data, uint8_t prefix) {
|
||||||
|
std::array<uint8_t,RIPEMD160_DIGEST_LENGTH + 1> hash{};
|
||||||
|
hash[0] = prefix;
|
||||||
|
RIPEMD160_CTX ctx;
|
||||||
|
RIPEMD160_Init(&ctx);
|
||||||
|
RIPEMD160_Update(&ctx, data.data(), data.size());
|
||||||
|
RIPEMD160_Final(hash.data() + 1, &ctx);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
template<ByteArray T>
|
template<ByteArray T>
|
||||||
std::array<uint8_t,RIPEMD160_DIGEST_LENGTH> hash160(const T& data) {
|
std::array<uint8_t,RIPEMD160_DIGEST_LENGTH> hash160(const T& data) {
|
||||||
return ripemd160(sha256(data));
|
return ripemd160(sha256(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<ByteArray T>
|
||||||
|
std::array<uint8_t,RIPEMD160_DIGEST_LENGTH + 1> hash160(const T& data, uint8_t prefix) {
|
||||||
|
return ripemd160(sha256(data), prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<ByteArray T>
|
||||||
|
std::array<uint8_t,SHA256_DIGEST_LENGTH> hash256(const T& data) {
|
||||||
|
return sha256(sha256(data));
|
||||||
|
}
|
||||||
|
|
||||||
template<ByteArray T>
|
template<ByteArray T>
|
||||||
std::string base58(const T& data)
|
std::string base58(const T& data)
|
||||||
{
|
{
|
||||||
|
|||||||
10
main.cpp
10
main.cpp
@ -7,7 +7,7 @@
|
|||||||
#include "Models/Block.h"
|
#include "Models/Block.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
std::string path = "/home/selim/dl/blk00000.dat";
|
std::string path = "/Users/selim/Documents/blk00000.dat"; //"/home/selim/dl/blk00000.dat";
|
||||||
std::fstream file(path);
|
std::fstream file(path);
|
||||||
|
|
||||||
std::vector<Block> blocks;
|
std::vector<Block> blocks;
|
||||||
@ -29,11 +29,11 @@ int main() {
|
|||||||
|
|
||||||
blocks.emplace_back(blockData.get(), header.blockSize);
|
blocks.emplace_back(blockData.get(), header.blockSize);
|
||||||
|
|
||||||
std::cout << "Parsed new block " << index++ << " with size: " << header.blockSize << std::endl;
|
//std::cout << "Parsed new block " << index++ << " with size: " << header.blockSize << std::endl;
|
||||||
|
|
||||||
if(index == 1000) {
|
// if(index == 171) {
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stop = std::chrono::high_resolution_clock::now();
|
auto stop = std::chrono::high_resolution_clock::now();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user