Fix for address calculation

This commit is contained in:
Selim Mustafaev 2021-05-10 21:24:30 +03:00
parent 853eec6038
commit 9284358def
5 changed files with 44 additions and 16 deletions

View File

@ -2,9 +2,13 @@ cmake_minimum_required(VERSION 3.19)
project(btcexplorer)
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}")
if(APPLE)
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
endif()
find_package(OpenSSL REQUIRED)
include_directories(OPENSSL_INCLUDE_DIR)

View File

@ -32,6 +32,10 @@ Script::Script(std::span<uint8_t> data, bool coinbase) {
}
ScriptType Script::type() const {
if(_operations.size() < 2) {
return ScriptType::Unknown;
}
if(_operations[0].opCode <= OpCode::OP_PUSHDATA4 && _operations[1].opCode == OpCode::OP_CHECKSIG) {
return ScriptType::P2PK;
} else if(_operations[0].opCode == OpCode::OP_DUP
@ -42,21 +46,19 @@ ScriptType Script::type() const {
{
return ScriptType::P2PKH;
} else {
throw std::runtime_error("Unsupported script type");
return ScriptType::Unknown;
//throw std::runtime_error("Unsupported script type");
}
}
std::string Script::address() {
auto pubKey = publicKey();
if(!pubKey.empty()) {
auto hash160 = hash::hash160(pubKey);
std::array<uint8_t, RIPEMD160_DIGEST_LENGTH + 1> prefixedHash{};
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);
auto hash160 = hash::hash160(pubKey, 0); // TODO: this value should depend on BlockMagic
auto secondHash = hash::hash256(hash160);
std::array<uint8_t, RIPEMD160_DIGEST_LENGTH + 1 + 4> finalHash{};
std::copy(prefixedHash.begin(), prefixedHash.end(), finalHash.begin());
std::copy_n(secondHash.begin(), 4, finalHash.begin() + prefixedHash.size());
std::copy(hash160.begin(), hash160.end(), finalHash.begin());
std::copy_n(secondHash.begin(), 4, finalHash.begin() + hash160.size());
return hash::base58(finalHash);
} else {
return "";
@ -66,6 +68,7 @@ std::string Script::address() {
std::span<uint8_t> Script::publicKey() {
switch (_type) {
case P2PK: return _operations[0].input;
case P2PKH: return _operations[2].input;
default: return {};
}
}

View File

@ -8,7 +8,7 @@ Transaction::Transaction(const std::byte *data) {
VarInt inputCount(data + sizeof(_version));
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) {
TxInput input(curPtr);
@ -21,7 +21,7 @@ Transaction::Transaction(const std::byte *data) {
for(size_t i = 0; i < outputCount.value(); ++i) {
TxOutput output(curPtr);
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));
}

21
hash.h
View File

@ -65,11 +65,32 @@ namespace 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>
std::array<uint8_t,RIPEMD160_DIGEST_LENGTH> hash160(const T& 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>
std::string base58(const T& data)
{

View File

@ -7,7 +7,7 @@
#include "Models/Block.h"
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::vector<Block> blocks;
@ -29,11 +29,11 @@ int main() {
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) {
break;
}
// if(index == 171) {
// break;
// }
}
auto stop = std::chrono::high_resolution_clock::now();