In this guide we’re going to dive into how to take a Solana keypair and break it its corresponding public and private keys.
Lets go ahead and use the Solana CLI to generate a new wallet with the keypair stored in a File System Wallet:
$ solana-keygen new --outfile ~/my-solana-wallet/demo.json Generating a new keypair For added security, enter a BIP39 passphrase NOTE! This passphrase improves security of the recovery seed phrase NOT the keypair file itself, which is stored as insecure plain text BIP39 Passphrase (empty for none): Wrote new keypair to /Users/matt/my-solana-wallet/demo.json ============================================================================= pubkey: HAE1oNnc3XBmPudphRcHhyCvGShtgDYtZVzx2MocKEr1 ============================================================================= Save this seed phrase and your BIP39 passphrase to recover your new keypair: favorite maid bind piece social father neutral over unusual tank brother code =============================================================================
This command generates a JSON file containing the keypair:
$ cat ~/my-solana-wallet/demo.json [4,182,130,247,119,117,227,207,112,73,170,126,222,197,244,99,215,107,255,202,33,43,36,17,104,111,157,246,196,192,174,95,240,23,238,206,118,215,154,238,229,96,11,37,156,123,51,223,5,231,17,117,86,136,103,14,75,95,175,132,148,54,1,46]
This is an array containing 64 values:
The first 32 values represent the private key:
private_key_bytes = [4, 182, 130, 247, 119, 117, 227, 207, 112, 73, 170, 126, 222, 197, 244, 99, 215, 107, 255, 202, 33, 43, 36, 17, 104, 111, 157, 246, 196, 192, 174, 95]
The second 32 values represent the public key:
public_key_bytes = [240, 23, 238, 206, 118, 215, 154, 238, 229, 96, 11, 37, 156, 123, 51, 223, 5, 231, 17, 117, 86, 136, 103, 14, 75, 95, 175, 132, 148, 54, 1, 46]
While this is the public key, it’s not in the same format as the public key displayed by the Solana CLI above. In order to format it that way, we need to convert this array of integer values into base 58.
In Ruby we’ll first convert the array to hex (base 16):
public_key_hex = public_key_bytes.pack("C*").unpack("H*").first
And then we can use a base 58 script to convert the hex into the base 58:
public_key = Base58.encode(public_key_hex)
And that gives us the same public key aka wallet address that we saw earlier in the Solana CLI output:
We can follow the same process to get the base 58 private key:
And also the base 58 keypair (which is the same thing you would get if you clicked the Export Private Key button in a Phantom Wallet, but note that it’s not actually the private key, it’s the keypair with both the private and public key – I suspect they call it that to make it clear to users that it includes the private key):
Try it yourself
1. Create a new folder
2. Create a file called
base58.rb and copy the base 58 Ruby script from this tutorial
3. Create another file named like
keypair.rb and paste in the following script:
4. Replace the content of
keypair_bytes with the value from your File System Wallet (you can use
solana config get to get the path to your keypair, then use the
cat command like above to get the content).
5. Then from the command line simply run
ruby keypair.rb to run the script:
$ ruby keypair.rb Keypair: 6Tyktf6mEqUMEKm2ZpLn3srEwk9zsT5jiE54EgPgToikMFYww1LGFUXgwgr6hvc9CikpaNaBH2vmkmqN3Usrxpd Public Key: HAE1oNnc3XBmPudphRcHhyCvGShtgDYtZVzx2MocKEr1 Private Key: KQ3cGFBdjJuRsB7U1K4to6cTGBPhgukqPgsi5pryr8v
Starting with a Base 58 Keypair
You can follow a similar process to take a base 58 keypair (like you would get from Export Private Key in a Phantom wallet) to derive the public and private keys:
$ ruby keypair58.rb Public Key: HAE1oNnc3XBmPudphRcHhyCvGShtgDYtZVzx2MocKEr1 Private Key: KQ3cGFBdjJuRsB7U1K4to6cTGBPhgukqPgsi5pryr8v
Thank you so much ,it is very useful.
Why the fuck would you write code in RUBY??? who the fuck uses RUBY???? write in PYTHON like normal people old man !!!!
I laughed :D