Skip to content

Instantly share code, notes, and snippets.

@evgenykuzyakov
Created September 3, 2020 23:48
Show Gist options
  • Save evgenykuzyakov/a0f1c0c4924107d798d79953655a4151 to your computer and use it in GitHub Desktop.
Save evgenykuzyakov/a0f1c0c4924107d798d79953655a4151 to your computer and use it in GitHub Desktop.
Doc for implicit account IDs

Implicit accounts

Background

Implicit accounts work similarly to Bitcoin/Ethereum accounts. It allows you to reserve an account ID before it's created by generating a ED25519 key-pair locally. This key-pair has a public key that maps to the account ID. The account ID is a lowercase hex representation of the public key. ED25519 Public key contains 32 bytes that maps to 64 characters account ID.

The corresponding secret key allows you to sign transactions on behalf of this account once it's created on chain.

Creating an account locally

Eventually near-cli will support generation of the implicit accounts in one command, but for now there is a workaround.

For a purpose of this demo, we'll use betanet network.

Set betanet network

export NEAR_ENV=betanet

Generating a key-pair first

near generate-key tmp1

Example Output

Generated key pair with ed25519:BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX public key

It generated a key-pair for tmp1 account ID. The new public key is ed25519:BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX. NEAR's string representation of a public key is <curve>:<data>.

  • Curve is either ed25519 or secp256k1. For implicit accounts we only support ed25519.
  • Data is a base58 encoding of the public key. For ed25519 it contains 32 bytes.

This command generated a key-pair locally and stored it locally at

~/.near-credentials/betanet/tmp1.json

Viewing the key-pair

Run to print the content of the key-pair file

cat ~/.near-credentials/betanet/tmp1.json

Content:

{"account_id":"tmp1","public_key":"ed25519:BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX","private_key":"ed25519:4qAABW9HfVW4UNQjuQAaAWpB21jqoP58kGqDia18FZDRat6Lg6TLWdAD9FyvAd3PPQLYF4hhx2mZAotJudVjoqfs"}

As you can see, it's a valid json-file and public key matches the one generated. The private_key is a secret/private key of the keypair that can be used to sign transactions with the corresponding public key.

Converting a public key to an account ID.

Let's convert a public key from NEAR string representation ed25519:BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX

The easiest way is to use near-cli with interactive console repl

Start near repl

near repl

Store your base58 public key to a local constant:

const pk58 = 'ed25519:BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX'

Now let's parse the public key and convert it to the hex in one line

nearAPI.utils.PublicKey.fromString(pk58).data.hexSlice()

The output string is the account ID in hex (without '):

'98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de'

So the new account ID is 98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de.

We can give this account ID to someone and ask them to transfer tokens.

Moving the temporary key-pair

Finally, we need to move tmp1.json key-pair to the real account ID, so that near-cli can use it to sign transactions.

Let's first export our account ID to a bash env variable:

export ACCOUNT="98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de"

Now we can move the tmp1.json file:

mv ~/.near-credentials/betanet/tmp1.json ~/.near-credentials/betanet/$ACCOUNT.json

NOTE: While .json key-pair file still contains the "account_id":"tmp1", it's okay. Because near-cli doesn't care.

Assuming you've received tokens on your new account, you can transfer from it using the following command:

near $ACCOUNT <receiver> <amount>

You can also replace $ACCOUNT with your actual account ID, e.g.

near 98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de <receiver> <amount>

Transferring to the implicit account

Let's say someone give you their account ID 0861ea8ddd696525696ccf3148dd706c4fda981c64d8a597490472594400c223, you can just transfer to it:

near <your_account_id> 0861ea8ddd696525696ccf3148dd706c4fda981c64d8a597490472594400c223 <amount>

BONUS: Converting public key using python (for learning purposes)

For this flow we'll use python3 (with version 3.5+) with base58 library.

You can install this library with pip3

pip3 install --user base58

Start python3 interpreter

python3

The first thing is to get the data part from the public key (without ed25519: prefix). Let's store it in a variable pk58

pk58 = 'BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX'

Now let's import base58

import base58

And finally let's convert our base58 public key representation to bytes and then to hex.

base58.b58decode(pk58).hex()

Output:

'98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de'

This give me the same account ID as near-cli, so this is encouraging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment