Skip to content

Commit

Permalink
Adding implicit account creation (#71)
Browse files Browse the repository at this point in the history
* Adding implicit account creation

* Update docs

* Update comment

Co-authored-by: Evgeny Kuzyakov <ek@nearprotocol.com>
  • Loading branch information
ilblackdragon and Evgeny Kuzyakov committed Sep 14, 2020
1 parent 6bc969b commit 103f3b1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
28 changes: 27 additions & 1 deletion specs/DataStructures/Account.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ NEAR Protocol has an account names system. Account ID is similar to a username.
- maximum length is 64
- **Account ID** consists of **Account ID parts** separated by `.`
- **Account ID part** consists of lowercase alphanumeric symbols separated by either `_` or `-`.
- **Account ID** that is 64 characters long consists of lowercase hex characters is a specific **implicit account ID**.

Account names are similar to a domain names.
Anyone can create a top level account (TLA) without separators, e.g. `near`.
Top level account (TLA) like `near`, `com`, `eth` can only be created by `registrar` account (see next section for more details).
Only `near` can create `alice.near`. And only `alice.near` can create `app.alice.near` and so on.
Note, `near` can NOT create `app.alice.near` directly.

Additionally, there is an implicit account creation path. Account ids, that are 64 character long, can only be created with `AccessKey` that matches account id via `hex` derivation. Allowing to create new key pair - and the sender of funds to this account to actually create an account.

Regex for a full account ID, without checking for length:

```regex
Expand Down Expand Up @@ -86,6 +89,29 @@ me@google.com // @ is not allowed (it was allowed in the past)
abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz
```


## Implicit account IDs

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 is 32 bytes that maps to 64 characters account ID.

Example: public key in base58 `BGCCDDHfysuuVnaNVtEhhqeT4k9Muyem3Kpgq2U1m9HX` will map to an account ID `98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de`.

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

### Implicit account creation

An account with implicit account ID can only be created by sending a transaction/receipt with a single `Transfer` action to the implicit account ID receiver:
- The account will be created with the account ID.
- The account will have a new full access key with the ED25519-curve public key of `decode_hex(account_id)` and nonce `0`.
- The account balance will have a transfer balance deposited to it.

This account can not be created using `CreateAccount` action to avoid being able to hijack the account without having the corresponding private key.

Once an implicit account is created it acts as a regular account until it's deleted.

## Account

[account]: #account
Expand Down
4 changes: 4 additions & 0 deletions specs/GenesisConfig/RuntimeFeeConfig/ActionCreationConfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ _type: Fee_

Base cost of making a transfer.

NOTE: If the account ID is an implicit account ID (64-length hex account ID), then the cost of the transfer fee
will be `transfer_cost + create_account_cost + add_key_cost.full_access_cost`.
This is needed to account for the implicit account creation costs.

## stake_cost

_type: Fee_
Expand Down
2 changes: 2 additions & 0 deletions specs/RuntimeSpec/Actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ for the rest of the actions until `DeleteAccount`. This gives permission by anot
pub struct CreateAccountAction {}
```

If `receiver_id` has length == 64, this account id is considered to be `hex(public_key)`, meaning creation of account only succeeds if followed up with `AddKey(public_key)` action.

**Outcome**:
- creates an account with `id` = `receiver_id`
- sets Account `storage_usage` to `account_cost` (genesis config)
Expand Down

0 comments on commit 103f3b1

Please sign in to comment.