validateaddress VS. listaddresses

+1 vote

I am building an app using multichain and I am using external wallet to generate keys and importing pubkey using importaddress(pubkey, rescan='false') using mcrpc [python client]. My next step is to make some operations on this key like granting permission and when I used this pubkey I got an error[mcrpc.exceptions.RpcError: Invalid address: 02c029deb8ff729988b68ecd0a17ecc535dbba47be1501ea041600beaa9fad4666

so I made a troublshooting using (validateaddress and listaddresses ) and I got 2 different representations for the same pubkey and both are working with grant

validateaddress('02c029deb8ff729988b68ecd0a17ecc535dbba47be1501ea041600beaa9fad4666')
{'isvalid': True, 'address': '19j94mnRPes5hEgbUWVT5N5tQ7mUeJezZyB2sE', 'ismine': False}

listaddresses output is '48j2dRc9VFHBq2cmEHW79wHJhw9gU9E12qL5Us'

I want to understand the logic here to deal with addresses in a right way and should I use public address or public key ?

Also how could we remove key from the node wallet after importing using importaddress(pubkey, rescan='false')?

asked Jun 30 by mina

1 Answer

+1 vote

A pubkey and an address are not the same thing – an address is calculated as a hash of the pubkey.

APIs like importaddress and validateaddress also support a pubkey as input, and will provide you with the corresponding address. But the grant API does not, so that's why you need to convert to an address first.

The listaddresses API shows all the addresses in the current wallet – are you sure that the address you're seeing in the output corresponds to that public key? You can pass true for the verbose parameter to see each address next to its corresponding pubkey.

As for the last question, you cannot remove keys/addresses from the node's wallet after importing them.

answered Jul 2 by MultiChain
Thank you for your clarifying for using pubKey and addresses for  APIs.But I still having the same problem as below for importing new address:
Before import address:

 client.listaddresses('*',True)
[{'address': '1BEBNtTP1JeSZNBuXCKAZ5oJirs8SMdhrtrBhu', 'ismine': True, 'iswatchonly': False, 'isscript': False, 'pubkey': '0210ee50d17fde536aa109ad697243a18d2c934965d56708d64a7af67bedc30df9', 'iscompressed': True, 'account': '', 'synchronized': True}, {'address': '4MFPUCrko6JWMgqsW71WgZ2xULPBHoUYdL9D3x', 'ismine': False, 'iswatchonly': True, 'isscript': True, 'script': 'nonstandard', 'hex': '', 'addresses': [], 'account': 'false', 'synchronized': True}, {'address': '42mfKA7ou2X72UA1mRU5gi2SZRn1jLLb91L2a1', 'ismine': False, 'synchronized': False}, {'address': '4EeSG4CwaZnCquJ6EWpoS9PKVzwizmCDhKAwBh', 'ismine': False, 'synchronized': False}, {'address': '48j2dRc9VFHBq2cmEHW79wHJhw9gU9E12qL5Us', 'ismine': False, 'synchronized': False}, {'address': '4QbGxQmyshoTughzPikqzASYMpmzoPuMSxapno', 'ismine': False, 'synchronized': False}]

To import address:'03acc5ff80c6a241be598312a650f5f941679012de1ddf13a6c7b101c91b90c233'
 client.importaddress('03acc5ff80c6a241be598312a650f5f941679012de1ddf13a6c7b101c91b90c233')

After importing:
client.listaddresses('*',True)
[{'address': '1BEBNtTP1JeSZNBuXCKAZ5oJirs8SMdhrtrBhu', 'ismine': True, 'iswatchonly': False, 'isscript': False, 'pubkey': '0210ee50d17fde536aa109ad697243a18d2c934965d56708d64a7af67bedc30df9', 'iscompressed': True, 'account': '', 'synchronized': True}, {'address': '4MFPUCrko6JWMgqsW71WgZ2xULPBHoUYdL9D3x', 'ismine': False, 'iswatchonly': True, 'isscript': True, 'script': 'nonstandard', 'hex': '', 'addresses': [], 'account': 'false', 'synchronized': True}, {'address': '42mfKA7ou2X72UA1mRU5gi2SZRn1jLLb91L2a1', 'ismine': False, 'synchronized': False}, {'address': '4EeSG4CwaZnCquJ6EWpoS9PKVzwizmCDhKAwBh', 'ismine': False, 'synchronized': False}, {'address': '48j2dRc9VFHBq2cmEHW79wHJhw9gU9E12qL5Us', 'ismine': False, 'synchronized': False}, {'address': '4QbGxQmyshoTughzPikqzASYMpmzoPuMSxapno', 'ismine': False, 'synchronized': False}, {'address': '4D5dmJUUnk7nRWuLpBcwSphb12TqzsPZrDrFTm', 'ismine': False, 'synchronized': False}]
The last address is the new imported address

>>> client.validateaddress('03acc5ff80c6a241be598312a650f5f941679012de1ddf13a6c7b101c91b90c233')
{'isvalid': True, 'address': '1E5kCeekh9hgHiyB4QcHNFWAhD5eB2pZPVojqn', 'ismine': False}

Be noted that the tool which i get the address to import give me that :
Address (Share):
19pnYqfXABc6s4TdJPiuEYkmdGv7R2cVKY

Public key (Share)
03acc5ff80c6a241be598312a650f5f941679012de1ddf13a6c7b101c91b90c233

Private key (WIF key)
KzA9vMaCVW62dUjga2rWNpxcyp1eepGnHN1C8CJ5ZFqkoNvfgj17
The difference between the address shown by your tool and what is shown in MultiChain will be due to the version bytes. Presumably your tool was made for bitcoin.

But apart from that I think you may have found a bug, which is that when a pubkey is imported using importaddress, it enters the wallet as a multisig rather than a regular address. I'll have the team look into this. But your solution for now is to use validateaddress to convert the pubkey to an address, and then import that address rather than the pubkey.
Having discussed this with the team, the answer is that you cannot use importaddress to import a public key, only an address. The MultiChain online documentation was mistaken in that regard and has now been fixed. If you pass a hexadecimal string to importaddress, the intended behavior is to treat it as a "redeem script" (for a pay-to-script-hash address) rather than a public key.
...