ethereumjs-wallet can be used to get public key from private key:
> const hdkey = require('ethereumjs-wallet/hdkey')
> const privateKey = hdkey.fromMasterSeed('random')._hdkey._privateKey
> const Wallet = require('ethereumjs-wallet')
> const wallet = Wallet.fromPrivateKey(privateKey)
> wallet.getPublicKeyString()
'0x11f2b30c9479ccaa639962e943ca7cfd3498705258ddb49dfe25bba00a555e48cb35a79f3d084ce26dbac0e6bb887463774817cb80e89b20c0990bc47f9075d5'
> wallet.getPublicKey()
<Buffer 11 f2 b3 0c 94 79 cc aa 63 99 62 e9 43 ca 7c fd 34 98 70 52 58 dd b4 9d fe 25 bb a0 0a 55 5e 48 cb 35 a7 9f 3d 08 4c e2 6d ba c0 e6 bb 88 74 63 77 48 ... >
Another option is to use ethereumjs-util (which is used by ethereumjs-wallet internally):
> const util = require('ethereumjs-util')
> util.privateToPublic(privateKey)
<Buffer 11 f2 b3 0c 94 79 cc aa 63 99 62 e9 43 ca 7c fd 34 98 70 52 58 dd b4 9d fe 25 bb a0 0a 55 5e 48 cb 35 a7 9f 3d 08 4c e2 6d ba c0 e6 bb 88 74 63 77 48 ... >
Yet another option is secp256k1:
> const secp256k1 = require('secp256k1')
> secp256k1.publicKeyCreate(privateKey, false).slice(1)
<Buffer 11 f2 b3 0c 94 79 cc aa 63 99 62 e9 43 ca 7c fd 34 98 70 52 58 dd b4 9d fe 25 bb a0 0a 55 5e 48 cb 35 a7 9f 3d 08 4c e2 6d ba c0 e6 bb 88 74 63 77 48 ... >
slice(1)
is to drop type byte which is hardcoded as 04
ethereum.
Agree with Sanchit about using modifiers to control access to functions.
However, the example implementation is misleading. I would flag that for a redesign.
A couple of things to consider.
As far a data storage is concerned, you might want to consider off-chain serialization with encryption. This, to reduce the overall storage cost without compromising the distributed nature of the app.
For privacy, I see you're aware that information in Ethereum is visible to all parties. Consider using multi-party encryption with a smart contract to help distribute the "secret" to multiple authorized parties.
For scalability, @Sanchit's modifier needs to eliminate the unbounded for
loop. Put simply, for(i=0;i<n;i++)
is an anti-pattern. At a certain n
the cost of execution will exceed the block gasLimit meaning it will fail in all cases. In other words, implemented that way guarantees a successful application will eventually fail, possibly in a way that can't be repaired.
What's shown is perfectly logical in a server-centric world. In Ethereum, all functions need an (approximately) fixed gas cost at any scale. A solution is to refactor with 1-step lookups using mapping
.
Just mentioning this because this error exists in a lot of contracts and I hope the answer (I generally agree) doesn't lead coders to replicate that sort of defect.
Hope it helps.
Best Answer
The concept of "degree verification" is a very cool idea. It's a subset of a larger idea called "attestations," and is pretty similar to what you describe.
An attestation, in it's most simple form, is a claim about you. Your college could attest to the fact that you are a student, your bank could attest that you are a "qualified investor," your co-workers could attest that you are skilled with Excel, etc. These attestations could be created in some standardized format and signed by the publicly known (and probably attested to) keys of others, as you describe.
These attestations you describe could underlie the basis of self-sovereign identity - where users could have complete control over their own data/identity. They could manage attestations made about them by a variety of third parties - disclosing only what they want to the parties who they want to know.
With the specific scheme you explore, I agree there might be some degree of unnecessary centralization. For example, it may be better to let the user generate the pub/priv key themselves. Even better, let them hold + manage all these attestations from with one key.
If users choose who to get attestations from and who to share these attestations with, users will have complete control over their own data and identity. I'd argue this is incredibly decentralizing.
Full disclosure, I'm an intern for uPort currently, which is a self-sovereign identity platform doing exactly this.
If you want more info and/or to chat, check out the uPort website, Gitter, or Github :~)