Skip to main content

Register accounts

Account registration allows you to create new accounts within the system. There are two methods for registering accounts: using an admin operation or defining a custom operation.

Registering with FT4 admin operation

The FT4 admin operation, ft4.admin.register_account requires an auth descriptor as a parameter. An auth descriptor specifies who can access an account, what actions they're allowed to perform, and the lifetime of the auth descriptor. The access to an account is determined by a public key when FT authentication (native Chromia signatures) is used or an EVM account address when an EVM wallet is used for authentication. The actions allowed by the auth descriptor are specified with authorization keys, and expiration rules determine the activation and validity duration of the auth descriptor. For more information, see auth descriptor.

To register an account using FT authentication, follow these steps:

  1. Generate a new key pair for the account and retrieve the public key:

    chr keygen --save .chromia/user.keypair | grep pubkey
  2. Register the account using the FT4 admin operation:

    chr tx ft4.admin.register_account \
    '[0, [["A","T"], x"0351D4F299E3D33EC745C9F3C2F74934960F58411BE8BAE52A1E6EC8D0BA26AEDB"], null]' \
    --await --secret .chromia/ft4-admin.keypair

    In the above command, 0 represents a single signature auth descriptor, while A (account) and T (transfer) are auth flags defined in the FT library. It's important to note that when calling FT account operations, such as ft4.add_auth_descriptor or ft4.delete_auth_descriptor, the authentication will fail unless the auth descriptor used has the A flag. Similarly, when calling the transfer operation, the transfer will be rejected if the auth descriptor doesn't have the T flag.

    In the above command, replace 0351D4F299E3D33EC745C9F3C2F74934960F58411BE8BAE52A1E6EC8D0BA26AEDB with the generated pubkey for the user.

  3. You can add a query that returns all accounts to verify if the account exists. Add the following query to your code:

    query get_all_accounts() = ft4.acc.account @* {} (.id);
  4. Update and wait for the blockchain to reflect the changes:

    chr node update
  5. You can now execute the query to retrieve all accounts:

    chr query get_all_accounts

    The output will display the account ID(s), such as:

    [x"5E2488889F72939DD4D0A034FB91893ACBF14C7EDBCEF2A9F5C621A07169EAD2"]

Registering with a custom operation

When registering an account with a custom operation, it's essential to protect the operation to prevent potential spam attacks on the blockchain. In this example, we require users to provide a voucher during registration. We must create a register and an admin operation to enable vouchers to be added.

  1. Define the voucher entity and the add_voucher operation in your code:

    entity voucher {
    hash: byte_array;
    mutable is_used: boolean = false;
    }

    operation add_voucher(hash: byte_array) {
    ft4.admin.require_admin();
    create voucher(hash);
    }
  2. Define the register_account operation, which includes voucher validation and account creation:

    operation register_account(ft4.acc.auth_descriptor, voucher_code: text) {
    // extract pubkey from auth descriptor
    val pubkey = byte_array.from_gtv(auth_descriptor.args[1]);

    // check if provided key is signer
    require(op_context.is_signer(pubkey), "Transaction needs to be signed by %s".format(pubkey));

    val hash = voucher_code.hash();
    val voucher = require(
    voucher @? { hash },
    "Provided voucher with code <%s> does not exist".format(voucher_code)
    );
    require(
    not voucher.is_used,
    "Provided voucher with code <%s> is already used".format(voucher_code)
    );
    voucher.is_used = true;
    ft4.acc.create_account_with_auth(auth_descriptor);
    }
  3. After adding the code snippets to the appropriate sections in your main.rell file, update the blockchain to apply the changes.

  4. Generate a voucher hash using the chr repl command as follows:

    chr repl -c '"voucher_1".hash()'

    The output would be a hash in the format:

    x"E1E72D0C6C975815BD3259D81E67253D98CF90D888B4C7CB393C8CFB9043BAF3"
  5. Add the voucher hash to the blockchain using the admin operation:

    chr tx add_voucher \
    'x"E1E72D0C6C975815BD3259D81E67253D98CF90D888B4C7CB393C8CFB9043BAF3"' \
    --await --secret .chromia/ft4-admin.keypair
  6. Generate a new keypair for the user who'll register the account, and retrieve the public key:

    chr keygen --save .chromia/user-2.keypair | grep pubkey
  7. Register the account using the custom operation register_account:

    chr tx register_account \
    '[0, [["A", "T"], x"03772E03AE22835384164AA90E28C84F78C97D29A2635861DC3F7E32F0CC8FDF51"], null]' \
    voucher_1 \
    --await --secret .chromia/user-2.keypair

    In the above command, replace 03772E03AE22835384164AA90E28C84F78C97D29A2635861DC3F7E32F0CC8FDF51 with the generated pubkey for the user.

  8. To verify the successful account registration, execute the get_all_accounts query again. You should now see two account IDs or one if you didn't follow the first half of the guide:

    chr query get_all_accounts

    The output would include the account IDs:

    [x"5E2488889F72939DD4D0A034FB91893ACBF14C7EDBCEF2A9F5C621A07169EAD2", x"79C71AF3C9C951BED380F8ADAB2E407C15CC4A9EB942AA222D870136C45801CE"]

Registering with an auth server

To simplify the registration process, we've built a basic backend app that allows you to rate-limit registrations to your blockchain. This app is called auth server.

When the auth server is running, people can register an account by following specific criteria. For more details about configuring the server, see auth server.