Skip to main content

Registry contract

Understand the Tableland Registry contract for SQL interactions.


Overview

The Tableland registry smart contract controls the creation and mutation of tables as well as access controls. When you interact with the registry contract, you pass raw SQL statements that are emitted and later materialized at the Tableland validator node.

When interacting the the registry, it's easiest to use a combination of the TablelandDeployments.sol and SQLHelpers.sol to form the SQL statements. You can choose to not use these libraries, but it's highly recommend to do so. You can check out examples for how to use these libraries in the Tableland Deployments and SQL Helpers pages, which outline how to use them with the registry methods. For example, you can chain TablelandDeployments.get().create(...) to create a table, and this pattern holds true for all of the other methods defined below.

create

Creates a new table owned by owner using statement and returns its tableId:

  • owner: The to-be owner of the new table.
  • statement: The CREATE TABLE SQL statement used to create the table.
function create(
address owner,
string memory statement
) external payable returns (uint256);

See the SQL Helpers page with an example for creating a table: here.

Batch create

An overloaded function also exists—the only difference is that statements is an array of CREATE TABLE statements, and the return type will be an array of table IDs:

function create(
address owner,
string[] calldata statements
) external payable returns (uint256[] memory);

See the SQL Helpers page with an example for creating multiple table: here.

mutate

Creates a new table owned by owner using statement and returns its tableId:

  • caller: The address that is running the SQL statement. The msg.sender must be caller, and the caller must be authorized by the table controller if the statement is mutating.
    • E.g., if a smart contract calls the registry, it'd use address(this) as the caller.
  • tableId: The ID of the target table.
  • statement: The SQL statement to run (INSERT, UPDATE, DELETE, GRANT, or REVOKE).
function mutate(
address caller,
uint256 tableId,
string calldata statement
) external payable;

See the SQL Helpers page with an example for a single INSERT statement against a table: here. The same pattern can be used for the other possible mutating methods noted above.

Batch mutate

An overloaded function can also be used. The difference is that statements is an array of ITablelandTables.Statement, defined as:

struct Statement {
uint256 tableId;
string statement;
}

The batching method is as follows:

function mutate(
address caller,
ITablelandTables.Statement[] calldata statements
) external payable;

See the SQL Helpers page with an example for multiple INSERT statements against a table. here, and there are other examples for UPDATES or DELETES as well.

getController

Get the current controller address for a table:

  • tableId: The id of the target table.
function getController(uint256 tableId) external returns (address);

If a table has its controller set (e.g., using setController), this method will return the corresponding address via a direct smart contract call. Otherwise, all tables default to the 0x0 address as being the table’s controller.

See the controllers page for an example: here.

setController

Set the controller address for a table:

  • caller: The address that is setting the controller. The msg.sender must be caller and owner of tableId
  • tableId: The ID of the target table.
  • controller: The address of the controller (EOA or contract).
function setController(
address caller,
uint256 tableId,
address controller
) external;

Only the table owner can set the controller of a table to an address, such as another account address or contract that implements the ITablelandController ACL policy. However, a table with a locked controller can no longer have its controller be set, again.

See the controllers page for an example: here.

lockController

Lock the controller address for a table:

  • caller: The address that is locking the controller. The msg.sender must be caller and owner of tableId
  • tableId: The id of the target table.
function lockController(address caller, uint256 tableId) external;

A table can have its controller permanently locked. This can be useful as a final ACL "lock" to ensure the table owner can no longer make any ACL changes (e.g., after some steady state in a production setting). Only the table owner can call this method.

See the controllers page for an example: here.

safeTransferFrom

Safely transfers a table between accounts (inherited from ERC721A)

  • from: The current owner of the table. The caller must own the token or be an approved operator.
  • to: The new owner of the table.
  • tokenId: The ID of the target table.
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;

See the Tableland Deployments page for example: here.