Everything in a contract is public so it is not a good idea to store the private keys inside a contract to decode messages. A hacker can determine your private key and create fake messages.
Also not a good idea to have a hardcoded private key in your mobile app. It is possible that a hacker can do a reverse engineering and find your keys.
It is hard to recommend something without more details. Probably I'd create a new pair private/public key on installation and store them in secure storage of the OS, and register the public key with your contract.
Now your app can sign transaction with its private key and send the signed message to the contract. The contract can use the ecrecover trick to recover the public key of the message signature and verify it is one of the registered in the contract.
You can use the web3.personal.newAccount(password)
method:
Generates a new account in the node’s keychain encrypted with the given passphrase
. Returns the address of the created account.
py>> web3.personal.newAccount('the-passphrase')
['0xd3cda913deb6f67967b99d67acdfa1712c293601']
Note that for security purposes, nodes do not expose the private key over the json-rpc
api that web3 uses. I'm not aware of a way to access your public key either.
If you want local keys instead of hosted keys, then check out: How can I generate a wallet in python?
Edit: it seems you really want both things: a local key and a hosted key at the same time. To accomplish that, you could create the key in the node and then extract it. That involves finding the file and decrypting it.
Where your keyfile is kept depends on your choice of node, OS, and configuration. I'll assume the default geth
keystore folder: ~/.ethereum/keystore/
You can decrypt the keyfile using the eth-account method decrypt()
:
from eth_account import Account
with open('~/.ethereum/keystore/<your_keyfile_name>') as keyfile:
keyfile_json = keyfile.read()
private_key = Account.decrypt(keyfile_json, '<you-account-password>')
# get some extra info about the private_key, like the address:
acct = Account.privateKeyToAccount(private_key)
ether_address = acct.address
You also asked about the public key, which is not an often used part of Ethereum, so there's no great API for it. You can use this non-public API, but note that these variable names could change at any time:
acct._key_obj.public_key
Best Answer
1) Follow the instructions in the second answer to implement spongycastle on Android. https://stackoverflow.com/questions/6898801/how-to-include-the-spongy-castle-jar-in-android
2) Download and import the slfj4 logger jar http://www.slf4j.org/android/
3) Download the latest ethereumj jar. Make sure you list the spongycastle jars first in your build.gradle dependencies, followed by slf4j, then ethereumj
4) You'll need to create new ethereum classes using spongy castle instead of bouncycastle. Here's the class I used to create private keys, sign them, etc. It's just a modified version of ethereumj's ECKey.class. Note that I included spongycastle here as a security provider, so don't make yourself a new class that includes it (this was mentioned in step 1)
To actually get this going in your app, try something like this: