How things work

I have a Factory contract, FContract.

FContract can be called by a user as many times as they want, creating instances of, let's call it, contractA. Thus, they're able to own as many contract instances of contractA, deployed by FContract, as they want.

Every instance of contractA can store distinct keys. Some keys are for this, some keys are for that, and some other keys are for signing purposes. So, inside the contract the user stores the sha3 of the public key that they created.

The user creates keys through the frontend (keys are not created by the contracts!). For example, the routine that the user calls to create keys, follows these steps (I found this on another project):

  1. Produce some randomHex(32) through web3.utils.randomHex(32)
  2. Concat 0's to the end of the produced hex, so it is == 67 digits
  3. set publicKey = web3.eth.accounts.privateKeyToAccount(privateKeyWithConcat).address
  4. set producedKey = web3.eth.utils.sha3(publicKey)

The issue & What I want to achieve

I want the users to be able to sign messages with the keys that they produced. They will choose one of the "signing keys" and then sign the message.

But the issue is that I do not have any idea on how to store (or retrieve) the private key.

Am I losing something?

Also, why hashing the public key by using sha3? What are the benefits of it? I can't really think of any, while storing the hashed public key instead of the real public key, uses much more space.

**Contracts interactions are done with Metamask

Edit: The only possible solution I can think of is that the user will have to "write down somewhere" the produced private key and, at the phase of signing, the system will ask him to provide it with it. But is this the only feasible solution?

1 Answer 1


I solved my issue the day after I posted here, but I wanted to check if it would work properly before posting in here again.

This is the solution that I implemented for my issue.

As I said, I need my users to be able and have as many keys as they want. So,

In the frontend, they ask for a new Key pair. This is what happens in the background:

var keyPair = state.web3.eth.accounts.create();
var key = state.web3.utils.sha3(keyPair.address)
return {

Now, my users can create as many keys as they want, simply by running a routine. But how are the keys stored in the smart-contract that every user owns? It's fairly easy: When users create a pair of keys, they must keep the private key somewhere safe. Then, they call a routine to store the keys to their smart-contract. In the smart-contract, this is what happens:

require(keys[_key].key != _key, "Key already exists!"); //Just in case...

Key memory newKeyStruct = Key(msg.sender, _key, _purpose);

keys[_key] = newKeyStruct;

Now, the public key is stored inside the smart contract and the private key is, safely stored, with the user.

Lastly, how can the user sign messages with his newly create key? This is the way I was able to think of. If anyone has a better idea, I will be glad to hear it =)

  1. Users choose the key with which they want to sign the message they were given (e.g. from a dropdown list)
  2. They import their private key
  3. They press Sign the message!

and, in the back-end, this is what happens:

let loadedAccount = state.web3.eth.accounts.privateKeyToAccount(privateKey)
let signature = loadedAccount.sign(state.web3.utils.soliditySha3(somethingToSign))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.