Skip to main content

Creating a smart account

This tutorial defines how smart accounts work in =nil; and outlines the different ways for creating a new smart account.

Definition

In =nil; a smart account is any smart contract that is able to pay for interactions with real-life users.

The traditional definition of a smart account in Ethereum mostly refers to externally-owned accounts (EOAs) that are secured via private keys and natively hold information about user's balances.

Smart accounts in =nil; differ from this definition. A =nil; smart account is always a smart contract, and it must be deployed as such. The smart account handles all the usual functionalities (e.g., authenticating requests) but it can also include complex logic such as multi-sig operations.

This means that in almost all cases an external message has to go through a smart account that signs the message and assigns a value to it. The message is only forwarded to its target smart contract for execution only after this process is complete.

Counterfactual contracts

It is possible to send funds to an address where a contract is supposed to be deployed. These funds will be stored at that address until the contract is finally deployed, at which point the contract will be able to access them.

Funds sent to an address without a deployed contract are safe, and another party cannot claim them by deploying another contract before the owners of the funds is able to deploy their own contract.

Pre-built and custom smart accounts

Because any smart contract can be a smart account. there is a distinction between pre-built and custom smart accounts.

A pre-built smart account is provided as part of =nil;. Such a smart account includes essential smart account functionalities as well as pre-defined constructor bytecode. The =nil; developer tools provide several ways of deploying pre-built smart accounts such as the nil smart-account new =nil; CLI command.

Pre-built smart accounts

Presently, only one type of pre-built smart accounts is available. Additional types of pre-built smart accounts are WIP.

Guarantees

As pre-built smart accounts are provided as part of =nil; they are guaranteed to be valid and tested. An audit process for pre-built smart accounts is currently under consideration.

A custom smart account is any smart contract written by a user. This contract can support any flow permitted by Solidity code such as multi-sig authorization or token vesting. Custom smart accounts can be deployed just like any other smart contract.

New smart account creation

Via the =nil; CLI

The =nil; CLI offers a quick and convenient way to create a new smart account:

nil smart-account new --salt SALT 

This will produce the following response:

Contract NEW_SMART_ACCOUNT_ADDRESS balance is topped up by 10000000
New smart account address: NEW_SMART_ACCOUNT_ADDRESS

This smart account essentially acts as a typical EOA: it supports basic asset management and authentication operations. The smart account should also be initialized with an initial balance (which is also seen in the initial command response). Send the following request to check this:

nil smart-account balance 
tip

The smart account can be 'topped up' by using the smart-account top-up AMOUNT command.

info

The smart-account new and the smart-account top-up commands only work in the =nil; devnet. The process for attaining tokens and 'topping up' an address will be different in the production network.

Via the client library

The Nil.js client library exposes the SmartAccountV1 class that allows for quickly creating and deploying a new smart account:

import { HttpTransport, PublicClient, generateSmartAccount } from "@nilfoundation/niljs";

const client = new PublicClient({
transport: new HttpTransport({
endpoint: RPC_ENDPOINT,
}),
shardId: 1,
});

const smartAccount = await generateSmartAccount({
shardId: 1,
rpcEndpoint: RPC_ENDPOINT,
faucetEndpoint: FAUCET_ENDPOINT,
});

This example initializes a new smart account. provides it with a Signer and requests a 'top up' to the smart account address. The smart account is then deployed.

Seqno

When using the client library, seqno defaults to 0 for every message sent via the smart account. If too many messages are sent at the same time with this seqno, they will fail. To avoid this issue, set the seqno manually whenever using the smart account:

smartAccount.sendMessage({
...
seqno: SEQNO,
...
})