Starksheet is a fully open-source fully on-chain software that aims at easing the access of on-chain data and logic. This README focuses on a technical description of Starksheet, for a more high-level contextual approach to Starksheet, please refer to our notion page.
From a smart contract point of view, Starksheet is a deployer contract,
deploying Sheets. A Sheet is, in turn, an NFT collection (actually a grid) of
contract calls (yes, the syscall
). These contract calls can reference others
calls like in a regular spreadsheet (or in
the Better Multicall):
A1=10
B1=SUM(A1, 20) // = 30
C1=SUM(A1, B1) // = 40
In other words, the cell C1
uses as input the output of A1
(the constant
value 10
) and B1
(the sum of A1
and 20
). If you are familiar with basic
spreadsheet operations this should look familiar.
The novelty of Starksheet is that the dapp doesn't own nor define any such SUM
function. Indeed, it only makes available to the user whatever is live on
chain. This means that for doing this simple SUM
operation, we need instead
to know a contract that implements this function, and call it:
- say that contract at address
0x1234
defines a function calledsum
sum
is called a selector and has a bytes representation (eitherbytes4
in the EVM world, or afelt
in Starknet); say it's0xabcd
.- the arguments of
sum
are the calldata of the call of selector0xabcd
at address0x1234
. This is either a bytes array (EVM) of a felt array (Starknet) of raw encoded data.
The encoding of the calldata depends on the network (EVM or Starknet) and reader is referred to their corresponding doc for a more detailed presentation of scheme.
When a user creates a sheet, they indeed deploy a regular ERC721 contract with few more features:
- the user can set the content of an NFT (a cell), the content being the above
mentioned tuple
(contract_address, selector, calldata)
- the rendering uses the computed value of the cell (ie its output value — 10, 30 or 40 in the example above)
- the rendering of the NFT (the result of
tokenURI
) is dynamically computed on chain whenever one callstokenURI
(no static uri)
In the previous example, rendering the token B1
would require to first render
A1
. For the renderer to know where the calldata of B1
was two constant
values or a constant value (20
) and the output of another cell (A1
), it uses
a flag being the first bit of the word (bytes32
or felt
):
- say A1 <> token Id #0, B1 <> token Id #1 and C1 <> token Id #2
- B1 is:
- contract_address: 0x1234
- selector: 0xabcde
- calldata:
- A1 => token Id #0 => 2 * 0 + 1 = 1
- 20 => constant => 2 * 20 + 0 = 40
This monorepo contains:
The Starknet and Solidity contracts do the same things, but target either Starknet or any EVM. The webapp is agnostic to the chain it targets (depending on a ENV variable).