How to get address from CTxIn object

1

1

I'm reading bitcoin core source code. I want to know how to get bitcoin address from CTxIn object.

I have a CTransaction object. I found the way how to get addresses from vout like the following. But I don't know about vin.

UniValue out(UniValue::VOBJ);
ScriptPubKeyToUniv(txout.scriptPubKey, out, true);

UniValue u = find_value(out, "addresses");
UniValue uv = u.getValues()[0];
newDestination = uv.get_str();

CTxIn has a scriptSig. I think I can get address from it.

CTxIn

https://dev.visucore.com/bitcoin/doxygen/class_c_tx_in.html


Update 1

I found how to get the pubkey by using ScriptToAsmStr. I know this works for only P2PKH address.

vector<string> array;
CScript s = _tx.vin[0].scriptSig;
string a = ScriptToAsmStr(s, true);
boost::algorithm::split(array, a, boost::is_any_of(" "));
if (array.size() == 2) {
    cout << array[1] << endl; // 0396f8781a4900372a5d72d84718d146170d5983e67dff8b4a28fef80690c09767
}

I'm now looking into how to convert the pubkey to bitcoin address on mainnet.


Update 2

I tried it like following but "invalid" is showed..

const char *cstr = "0396f8781a4900372a5d72d84718d146170d5983e67dff8b4a28fef80690c09767";
std::vector<unsigned char> vec(cstr, cstr + strlen(cstr));

CPubKey pubkey(vec);
if (pubkey.IsValid()) {
    cout << "valid" << endl;    
} else {
    cout << "invalid" << endl;
}

Update 3

Thanks to the Andrew Chow's answer, I could make a CPubKey object. All that is left is to output the bitcoin address from the object.

#include "utilstrencodings.h"

std::vector<unsigned char> vec = ParseHex("0396f8781a4900372a5d72d84718d146170d5983e67dff8b4a28fef80690c09767");

CPubKey pubkey(vec);
if (pubkey.IsValid()) {
    cout << "valid" << endl;
} else {
    cout << "invalid" << endl;
}

Update 4

Finally, I got a bitcoin address from a CTxIn object. I think this is not smart way. There might be other ways. And still not sure about CKeyID's meaning. I will look into it in detail.

CKeyID id = pubkey.GetID();
CBitcoinAddress address(id);
if (address.IsValid()) {
    cout << "valid" << endl;    
} else {
    cout << "invalid" << endl;
}

cout << address.ToString() << endl; // 15L7U55PAsHLEpQkZqz62e3eqWd9AHb2DH

zono

Posted 2017-06-16T09:16:14.153

Reputation: 1 569

Answers

4

I suppose you are the same person who made this thread on bitcointalk: https://bitcointalk.org/index.php?topic=1969807.0

I'll answer you here too to help other people too.


You are treating the pubkey as a string, but it is really a blob of binary data that is 33 bytes long. What you want to do instead is initialize an array with your pubkey and then use that to initialize your CPubKey.

Your code should look like this:

unsigned char pk[] = {0x03, 0x96, 0xf8, 0x78, 0x1a, 0x49, 0x00, 0x37, 0x2a, 0x5d, 0x72, 0xd8, 0x47, 0x18, 0xd1, 0x46, 0x17, 0x0d, 0x59, 0x83, 0xe6, 0x7d, 0xff, 0x8b, 0x4a, 0x28, 0xfe, 0xf8, 0x06, 0x90, 0xc0, 0x97, 0x67};
std::vector<unsigned char> vec(pk, pk+ sizeof(pk));

CPubKey pubkey(vec);
if (pubkey.IsValid()) {
    cout << "valid" << endl;    
} else {
    cout << "invalid" << endl;
}

Andrew Chow

Posted 2017-06-16T09:16:14.153

Reputation: 40 910