Bitcoin Forum
May 09, 2024, 07:24:36 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: ScriptHash to CKeyID  (Read 174 times)
liorko87 (OP)
Newbie
*
Offline Offline

Activity: 29
Merit: 6


View Profile
May 24, 2021, 09:47:34 AM
Last edit: May 24, 2021, 09:59:54 AM by liorko87
Merited by NotATether (2), ABCbits (1), Heisenberg_Hunter (1)
 #1

I have a valid base58 address that I got using getnewaddress command.
I'm trying to convert it to CKeyID object but I have some difficulties.

The problematic code:

Code:
string sKey = "my_address"; // it's not the real address
std::vector<unsigned char> prefix = std::vector<unsigned char>(1,5);
CTxDestination dest = ::DecodeAddressDestination(sKey, prefix);
CScript script = GetScriptForDestination(dest);
CKeyID key = CKeyID(script);

I also tried this way:
Code:
CKeyID key;
key.SetHex(sKey);

The second way printed me this value, which is incorrect: 000000000000000000000000000000000000000b

At the debugging I can see that dest value is ScriptHash
What I'm doing wrong?
1715282676
Hero Member
*
Offline Offline

Posts: 1715282676

View Profile Personal Message (Offline)

Ignore
1715282676
Reply with quote  #2

1715282676
Report to moderator
1715282676
Hero Member
*
Offline Offline

Posts: 1715282676

View Profile Personal Message (Offline)

Ignore
1715282676
Reply with quote  #2

1715282676
Report to moderator
1715282676
Hero Member
*
Offline Offline

Posts: 1715282676

View Profile Personal Message (Offline)

Ignore
1715282676
Reply with quote  #2

1715282676
Report to moderator
Even in the event that an attacker gains more than 50% of the network's computational power, only transactions sent by the attacker could be reversed or double-spent. The network would not be destroyed.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1715282676
Hero Member
*
Offline Offline

Posts: 1715282676

View Profile Personal Message (Offline)

Ignore
1715282676
Reply with quote  #2

1715282676
Report to moderator
1715282676
Hero Member
*
Offline Offline

Posts: 1715282676

View Profile Personal Message (Offline)

Ignore
1715282676
Reply with quote  #2

1715282676
Report to moderator
NotATether
Legendary
*
Offline Offline

Activity: 1596
Merit: 6732


bitcoincleanup.com / bitmixlist.org


View Profile WWW
May 24, 2021, 02:02:51 PM
 #2

Is it a P2SH or P2[W]PKH address?

Where does ::DecodeAddressDestination come from? It is not an API function and the double colons indicate it's in the same class as your problematic code.

CKeyID expects to be initialized with a uint160 but as far as I can see, CScript does not have a hashing method to return one.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
liorko87 (OP)
Newbie
*
Offline Offline

Activity: 29
Merit: 6


View Profile
May 24, 2021, 02:18:33 PM
 #3

The address is P2SH.
DecodeAddressDestination is a function that I added to base58.cpp. I added the implementation.

Code:
CTxDestination DecodeAddressDestination(const std::string& str, const std::vector<unsigned char>& pubkey_prefix) {
        std::vector<unsigned char> data;
        uint160 hash;
        if (DecodeBase58Check(str, data, 256)) {

        // base58-encoded Bitcoin addresses.
        // Public-key-hash-addresses have version 0 (or 111 testnet).
        // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
        if (data.size() == hash.size() + pubkey_prefix.size() &&
        std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
            std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
            return ScriptHash(hash);
            }
        }
        return CNoDestination();
}
NotATether
Legendary
*
Offline Offline

Activity: 1596
Merit: 6732


bitcoincleanup.com / bitmixlist.org


View Profile WWW
May 24, 2021, 02:57:20 PM
 #4

There is a uint160 returned by DecodeBase58Check, why aren't you using that?

Only ScriptHash can extract the uint160 using begin() and end() iterators inherited from its superclass. When you turn it into a CTxDestination you lose the bytes because it's converted into a vector<unsigned char> of opcodes which hashes into something different.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
liorko87 (OP)
Newbie
*
Offline Offline

Activity: 29
Merit: 6


View Profile
May 24, 2021, 03:01:54 PM
 #5

According to DecodeBase58Check signature it's returns bool and not hash160:

Code:
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret)

Did you meant to vchRet?
NotATether
Legendary
*
Offline Offline

Activity: 1596
Merit: 6732


bitcoincleanup.com / bitmixlist.org


View Profile WWW
May 24, 2021, 04:09:07 PM
Merited by ABCbits (1)
 #6

According to DecodeBase58Check signature it's returns bool and not hash160:

Code:
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret)

Did you meant to vchRet?

Yes that's what I meant, I had already read the Doxygen classes on doxygen.bitcoincore.org.

So what you can do is reuse code from your DecodeAddressDestination to generate the CKeyID that is made from the base58-to-uint160 process like so:

Code:
         string sKey = "my_address";
        std::vector<unsigned char> prefix = std::vector<unsigned char>(1,5);
        std::vector<unsigned char> data;
        uint160 hash;
        if (DecodeBase58Check(sKey, data, 256)) {
               // For your example the checks can be skipped since you have already
               // verified it returns a ScriptHash()
               std::copy(data.begin() + prefix.size(), data.end(), hash.begin());
               CKeyID key = CKeyID(hash);
        }

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
liorko87 (OP)
Newbie
*
Offline Offline

Activity: 29
Merit: 6


View Profile
May 25, 2021, 07:42:03 AM
 #7

@NotATether I missed your comment yesterday, thank you for your help, it solved my problem.
develCuy
Sr. Member
****
Offline Offline

Activity: 470
Merit: 350



View Profile WWW
February 10, 2022, 05:25:32 AM
 #8

For those looking to get CKeyID, you might be going the wrong path (like I did). I needed to convert an address in String format into a hash that can make into a custom transaction, which is something that Devcoin does in order to transfer a certain amount of newly minted coins to a list of addresses (beneficiaries).

Little context, currently I'm updating Devcoin from old Bitcoin 0.8.x up to Bitcoin Core 22.x, so many things have changed! Also, I was missing the fact that Bitcoin transactions need pubkey hashes, not the actual pubkeys. An address derives from a pubkey hash, which then derives from a pub key. Btw, there is no way back from hashes to pub keys, since that would break the actual purpose of hashes (they are irreversible). Hopefully, address are base58 formatted, it means that they are reversible to their hash. Last but not least, modern Bitcoin has great functions that handle the different types of addresses and their hashes, so we do the following:

Code:
CMutableTransaction myTx;
myTx.vin.resize(1);
myTx.vin[0].prevout.SetNull();

const string addressString = "my_address";
CAmount amount = 10;
string error_str;
CTxDestination destination = DecodeDestination(addressString, error_str);

// You don't need much more checks than the following
if (!IsValidDestination(destination)) {
   return error(error_str);
}

CScript pubKeyHash = GetScriptForDestination(destination);
myTx.vout[0] = CTxOut(amount, pubKeyHash);

An implementation of the above: https://github.com/devcoin/core/blob/4ec355c0e42108afcfc8d2467fdeed0119a4123b/src/miner.cpp#L163

- develCuy

Join Devcoin: Telegram, Reddit, Discord, Facebook, Keybase  | The Devcoin Project - from the many, one. From one, the source
NotATether
Legendary
*
Offline Offline

Activity: 1596
Merit: 6732


bitcoincleanup.com / bitmixlist.org


View Profile WWW
February 10, 2022, 06:28:30 PM
 #9

Little context, currently I'm updating Devcoin from old Bitcoin 0.8.x up to Bitcoin Core 22.x, so many things have changed!

Interesting. How did you manage to migrate the C++98(??) codebase all the way to the present C++17 codebase?

I have attempted to retrofit parts of Bitcoin Core to other programs but spent many days downgrading them to C++11 equivalents, such is how deeply engrained they are that the only feasible way to do it would be to fit your existing modifications on to the Core codebase instead of the other way around (I believe this is why many forks are stuck on old versions of Core perpetually).

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!