OmniLayer / omniwallet

Omni Protocol Hybrid Web-Wallet
https://www.omniwallet.org
GNU Affero General Public License v3.0
327 stars 187 forks source link

Addresses without pubkeys on the blockchain can't be used to send funds #96

Closed curtislacy closed 10 years ago

curtislacy commented 10 years ago

[2/28/14 9:35:15 AM] Curtis Lacy: I'm trying to send from 14wmRvD4E1e7fcx35TYy1MZbJcYHCCMbTA [2/28/14 9:35:31 AM] Curtis Lacy: masterchain.info won't let me do it either, it says "no pubkey on blockchain. use wallet or supply Public Key from brainwallet.org" [2/28/14 9:37:58 AM] Curtis Lacy: I had a question about this a while back, but wasn't sure how I got into that state and everyone assured me I was wrong. [2/28/14 9:39:07 AM] Curtis Lacy: So it seems like we need a way to get the public key from the private key (which we have already in order to perform the send anyhow).

Here's the error I get on the server when I try to use the address above:

Traceback (most recent call last):
  File "./send.py", line 209, in send_handler
    return general_handler(environ, start_response, send_form_response)
  File "./msc_apps.py", line 34, in general_handler
    (response, error)=response_dict_to_response_func(response_dict)
  File "./send.py", line 76, in send_form_response
    tx_to_sign_dict=prepare_send_tx_for_signing(from_addr, to_addr, marker_addr, currency_id, amount, btc_fee)
  File "./send.py", line 166, in prepare_send_tx_for_signing
    change_address_compressed_pub=get_compressed_pubkey_format(get_pubkey(changeAddress))
  File "/home/cmlacy/omniwallet/node_modules/mastercoin-tools/msc_utils_bitcoin.py", line 112, in get_compressed_pubkey_format
    public_pair=encoding.sec_to_public_pair(encoding.binascii.unhexlify(pubkey))
TypeError: Non-hexadecimal digit found
ghost commented 10 years ago

I'm confused, since you need to fund an account initially, it implies that some funds would always be sent to an address before its used; is that not the case?

curtislacy commented 10 years ago

I can't even explain how this happens. When I tried to ask on the list about it a few weeks ago the general consensus was that I had no idea what I was talking about. I do know that if you go to masterchain.info and verify that address as a sender, it'll complain that it doesn't have a pubkey on the blockchain.

@maran seems to think this is an easy thing to get from the library that we use to generate addresses and private keys.

ghost commented 10 years ago

Its pretty simple if we have a private key, but you can't otherwise. The command is just (you can try this in the console while visiting omniwallet labs) ; var key = new Bitcoin.ECKey.decodeEncryptedFormat(privkey, passphrase); key.getPubKeyHex(); if I'm not mistaken. You ought to double check, but I'm pretty sure thats all it is.

dexX7 commented 10 years ago

Multisignature transactions require explicitly public keys (length: 33 byte compressed, 65 byte uncompressed, usually hex encoded, starting with 02, 03 or 04) as input and not the public key hash aka. the normal address (1..., length: 27-34 base58 encoded).

It's probably a bit missleading that masterchain.info states "sender address or public key". The public key can be generated from the private key and the normal address from the public key, but not the other way around. "bitcoind validateaddress 1addr.." can be used to get the pubkey for an address you own though. The Bitcoin wiki has a great example of transformation. (link)

Edit: related: https://github.com/grazcoin/mastercoin-tools/issues/4#issuecomment-35979506

ripper234 commented 10 years ago

Tagging Medium (change the severity if you disagree with me)

curtislacy commented 10 years ago

I think it's actually higher than medium, but no matter. I'm working on it this morning.

curtislacy commented 10 years ago

I was able to get an error by creating a new address on bitaddress.org, and then trying to send it a TMSC first thing:

Funds could not be sent: Error sending transaction: Cannot read property 'length' of undefined
curtislacy commented 10 years ago

Sending BTC to that address worked fine. Root error from the server was "Invalid amount" when trying to send TMSC.

curtislacy commented 10 years ago

As a further clarification, it appears that the pubkey issue applies to any address that has not yet been used to SEND BTC. You can't send MSC or TMSC from an address until after you've sent at least a little BTC from that address, currently.

dexX7 commented 10 years ago

For me it sounds like the backend tries to scan the blockchain for a transaction made by the address to extract the pubkey from there (pubkeys are exposed when sending) and fails in this case. Masterchain probably chose this way, because there it's also possible to sign the transaction on your own. But in all cases we are in possession of the private key, so the direct way would be to derive the public key from the private key.

To quote @faizkhan00:

Its pretty simple if we have a private key, but you can't otherwise. The command is just (you can try this in the console while visiting omniwallet labs) ; var key = new Bitcoin.ECKey.decodeEncryptedFormat(privkey, passphrase); key.getPubKeyHex(); if I'm not mistaken. You ought to double check, but I'm pretty sure thats all it is.

curtislacy commented 10 years ago

Yep, I believe that's it exactly. The trick is that the server isn't in posession of the private keys, in our case (since we inhertied so much of this from masterchain). I just need to figure out how to get it in there at the right place in the flow. Maybe just always specify the public key from the client.

curtislacy commented 10 years ago

Fixed by #132.