Author: Shew & Faust, geek web3
Summary
The main technical features of Starknet, including the benefits ZK proves that the generated Cairo language, native-level AA, and smart contract model are independent of business logic and state storage.
Cairo is a universal ZK language that can be used to implement smart contracts on Starknet and to develop more traditional applications. The introduction of Sierra as an intermediate language in the compilation process allows Cairo to iterate frequently without having to change the lowest bytecode. It only needs to transfer the changes to the intermediate language; inCairo’s standard library, accounts are also included Many basic data structuresrequired for abstraction.
Starknet smart contracts store business logic and status data separately. Different from the EVM chain, Cairo contract deployment includes "compilation, declaration, deployment" In the third stage, the business logic is declared in the Contract class. The Contract instance containing the status data can be associated with the class and call the code contained in the latter;
- < p>The above-mentioned smart contract model of Starknet is conducive to code reuse, contract state reuse, storage stratification, and detection of junk contracts. It is also conducive to the realization of storage leasing and transaction parallelization. Although the latter two have not yet been implemented, the structure of Cairo smart contracts has created "necessary conditions" for them.
There are only smart contract accounts on the Starknet chain, and there are no EOA accounts. It supports native-level AA account abstraction from the beginning. Its AA plan absorbs the ideas of ERC-4337 to a certain extent, allowing users to choose highly customized transaction processing solutions. In order to prevent potential attack scenarios, Starknet has taken many countermeasures and made important explorations into the AA ecosystem.
Following the issuance of tokens by Starknet, STRK It has gradually become one of the indispensable elements in the eyes of Ethereum observers. This Ethereum Layer 2 star, who has always been known for being "maverick" and "not paying attention to user experience", is like a hermit who lives in isolation from the world, quietly carving out his own niche in the Layer 2 ecosystem where EVM compatibility is prevalent. .
Because it ignored users too much and even publicly opened an "electronic beggar" channel on Discord, Starknet was once criticized by the Lu Mao Party. While being criticized for being "unhuman", it had profound technical attainments. Becoming "worthless" in an instant, it seems that only UX and wealth-creating effects are everything. The sentence "Not being understood by others has become my only pride" in "The Temple of the Golden Pavilion" is simply Starknet's self-portrait.
But putting aside these trivial matters, purely based on the "technical taste" of code geeks, Starknet and StarkEx, one of the pioneers of ZK Rollup, are almost treasures in the eyes of Cairo enthusiasts. In some cases, In the minds of full-chain game developers, Starknet and Cairo are simply everything in web3, and neither Solidity nor Move can compare with them. The biggest generation gap between “technology geeks” and “users” today is actually more attributable to people’s lack of awareness of Starknet.
With the interest and desire to explore blockchain technology, and the discovery of the value of Starknet, the author of this article starts from Starknet’s smart contract model and native AA to simplify it for everyone. Sorting out its technical solutions and mechanism design,While showing Starknet's technical features to more people, we also hope to let people understand this "lone ranger that is not understood by others."
Cairo language minimalist science
In the following we will focus on Starknet’s smart contract model and native account abstraction, and explain how Starknet implements native AA . After reading this article, everyone can also understand why the mnemonic phrases of different wallets in Starknet cannot be mixed.
But before introducing the native account abstraction, let us first understand Starknet’s original Cairo language. During the development of Cairo, an early version named Cairo0 appeared, and later a modern version. The overall syntax of the modern version of Cairo is similar to Rust, and it is actually a general ZK language. In addition to writing smart contracts on Starknet, it can also be used for the development of general applications.
For example, we can use Cairo language to develop the ZK authentication system. This program can be run on the server we built without relying on the StarkNet network. It can be said that any program that requires verifiable computational properties can be implemented in the Cairo language. AndCairo may be the most conducive programming language for generating ZK proofs at present.
From the compilation process, Cairo uses an intermediate language-based The compilation method is as shown in the figure below. Sierra in the picture is an intermediate form (IR) in the Cairo language compilation process, and Sierra will be compiled into a lower-level binary code form, named CASM, which runs directly on the Starknet node device.
Introducing Sierra as an intermediate form to facilitate the addition of new features to the Cairo language. In many cases, we only need to manipulate the Sierra intermediate language without directly changing the underlying CASM code. This saves a lot of trouble and the Starknet node client does not need to be updated frequently. In this way, frequent iterations of the Cairo language can be achieved without changing the underlying logic of StarkNet. Cairo's standard library also includes many basic data structures required for account abstraction.
Cairo’s other innovations include a theoretical solution called Cairo Native, which plans to compile Cairo into low-level machine code that can adapt to different hardware devices, and Starknet nodes are running When writing smart contracts, there is no need to rely on the CairoVM virtual machine, which can greatly improve the code execution speed [it is still in the theoretical stage and has not yet been implemented].
Starknet smart contract model: separation of code logic and state storage< /strong>
Unlike EVM-compatible chains, Starknet has made breakthrough innovations in the design of smart contract systems. These innovations are largely prepared for native AA and parallel transaction functions that will be launched in the future. Here, we need to know that on traditional public chains such as Ethereum, the deployment of smart contracts often follows the "deployment after compilation" method. Take the ETH smart contract as an example:
1 .After the developer writes the smart contract locally, he compiles the Solidity program into EVM bytecode through the editor, so that it can be directly understood and processed by EVM;
2. The developer initiates a deployment The transaction request of the smart contract deploys the compiled EVM bytecode to the Ethereum chain.
(Picture source: not-satoshi.com)
Although Starknet’s smart contracts also follow the idea of “compile first and then deploy”,Smart contracts are deployed on the chain in the form of CASM bytecode supported by CairoVM.However, there are huge differences between Starknet and EVM-compatible chains in the calling method and state storage mode of smart contracts.
To be precise, Ethereum smart contract = business logic + status information. For example, the USDT contract not only implements common functions such as Transfer and Approval, but It also stores the asset status of all USDT holders.The code and status are coupled together, which brings a lot of troubles. First of all, it is not conducive to DAPP contract upgrade and status migration, and it is not conducive to parallel processing of transactions. A heavy technical baggage.
In this regard, Starknet has improved the state storage method ,In its smart contract implementation plan, DAPP’s business logic and asset status are completely decoupled and stored in different places. The benefits of this are obvious. First, it allows the system to distinguish more quickly. Are there duplicate or redundant code deployments? The principle here is as follows:
Ethereum’s smart contract = business logic + status data. If there are several contracts that have exactly the same business logic but different status data, then The hashes of these contracts are also different. At this time, it is difficult for the system to distinguish whether these contracts are redundant and whether there are "junk contracts".
AndIn Starknet's solution, the code part and status data are directly separated. Based on the hash of the code part, the system can more easily tell whether the same code has been deployed multiple times. Because their hashes are the same. This will help prevent repeated code deployment and save storage space on Starknet nodes.
In Starknet's smart contract system, the deployment and use of contracts are divided into three stages: "Compilation, Declaration, and Deployment". If an asset issuer wants to deploy a Cairo contract, the first step is to compile the written Cairo code locally on their own device into Sierra and the underlying bytecode CASM form.
Then, the contract deployer issues a "declare" transaction to deploy the contract's CASM bytecode and Sierra intermediate code to the chain, named Contract Class.
(Picture source: Starknet official website)
After that, if you want to use the function defined in the asset contract, you can initiate a "deploy" transaction through the DAPP front-end , deploy a Contract instance associated with the Contract Class, and the asset status will be stored in this instance. After that, the user can call the function function in the Contract Class to change the status of the Contract instance.
In fact, anyone who understands object-oriented programming should be able to easily understand what Class and Instance represent in Starknet. The Contract Class declared by the developer only contains the business logic of the smart contract. It is a function that anyone can call. However, it does not have the actual asset status, so it does not directly implement the "asset entity", only the "soul". "flesh".
Whenthe user deploys a specific Contract instance, the asset is "materialized". If you want to change the status of the asset "entity", such as transferring your token to someone else, you can directly call the function written in the Contract Class. The above process is somewhat similar (but not exactly the same) to "instantiation" in traditional object-oriented programming languages.
p>
After smart contracts are separated into Classes and instances, business logic and status data are decoupled, bringing the following features to Starknet:
1. Conducive to storage tiering and "storage The implementation of "rental system"
The so-called storage tiering means that developers can place data in customized locations according to their own needs, such as under the Starknet chain. StarkNet is ready to be compatible with DA layers such as Celestia, and DAPP developers can store data in these third-party DA layers. For example, a game can store its most important asset data on the Starknet mainnet, and store other data in off-chain DA layers such as Celestia. This solution of customizing the DA layer according to security requirements was named "Volition" by Starknet.
The so-called storage rental system means that everyone should continue to pay for the storage space they occupy. As much space on the chain as you occupy, you should theoretically continue to pay rent.
In the Ethereum smart contract model, the ownership of the contract is unclear, and it is difficult to distinguish whether the deployer or the asset holder should pay "rent" for an ERC-20 contract, The storage leasing function has not been launched for a long time, and the deployer is only charged a fee when the contract is deployed. This storage fee model is unreasonable. < /p>
2. Realize true code reuse and reduce the deployment of junk contracts
We can declare a general token contract to be stored on the chain as a class. Then everyone can call the function in this class to deploy their own token instance. Moreover, the contract can also directly call the code in the class, which achieves an effect similar to the Library function library in Solidity.
At the same time, Starknet’s smart contract model helps to identify “junk contracts”. This was explained earlier. After supporting code reuse and junk contract detection, Starknet can significantly reduce the amount of data uploaded to the chain and reduce the storage pressure on nodes as much as possible.
3. Real contract “state” reuse
Contract upgrades on the blockchain mainly involve changes in business logic, in the Starknet scenario Under the circumstances, the business logic and asset status of smart contracts are naturally separated. If the contract instance changes the associated contract type class, the business logic upgrade can be completed without migrating the asset status to a new place. This form of contract upgrade is better than Ethereum. more thorough and original.
To change the business logic of an Ethereum contract, it is often necessary to "outsource" the business logic to an agency contract, and change the business logic of the main contract by changing the dependent agency contract. However, this This method is not concise enough and "not native".
(Image source: wtf Academy)
In some scenarios, if the old Ethereum contract is completely abandoned, the asset status inside cannot be directly migrated It is very troublesome to move to a new place; the Cairo contract does not need to migrate the state and can directly "reuse" the old state.
4. Conducive to parallel processing of transactions
To improve the parallelism of different transaction instructions as much as possible, a necessary step is to combine the asset status of different people Decentralized storage, which can be seen in Bitcoin, CKB and Sui. The prerequisite for the above goal is to separate the business logic of smart contracts from asset status data. Although Starknet has not yet carried out in-depth technical implementation of parallel transactions, it will regard parallel transactions as an important goal in the future.
Starknet’s native AA and account contract deployment
In fact, the so-called account abstraction and AA are unique inventions invented by the Ethereum community Concept, in many new public chains, there is no distinction between EOA accounts and smart contract accounts, avoiding the pitfalls of the Ethereum-style account system from the beginning. For example, under the setting of Ethereum, the EOA account controller must have ETH on the chain before he can initiate a transaction. There is no way to directly choose a variety of authentication methods, and it is extremely troublesome to add some customized payment logic. Some people even think that the account design of Ethereum is simply anti-human.
If we look at chains such as Starknet or zkSyncEra that focus on "native AA", we can observe obvious differences: First, Starknet and zkSyncEra have unified account types. There are only smart contract accounts on the chain, and there is no such thing as an EOA account from the beginning (zkSync Era will deploy a set of contract codes by default on the user's newly created account to simulate the characteristics of the Ethereum EOA account, so It is convenient for compatibility with Metamask).
And Starknet has not considered direct compatibility with Ethereum peripheral facilities such as Metamask, When a user uses the Starknet wallet for the first time, a dedicated contract account will be automatically deployed. To put it bluntly, it is to deploy the contract instance mentioned above.This contract instance will be associated with the contract class deployed in advance by the wallet project and can be called directly Some functions written in class.
We will talk about an interesting topic below: When receiving the STRK airdrop, many people found that Argent and Braavos wallets are not compatible with each other. After importing Argent’s mnemonic phrase into Braavos , the corresponding account cannot be exported. This is actually because Argent and Braavos use different account generation calculation methods, resulting in different account addresses generated for the same mnemonic phrase.
Specifically, in Starknet, the newly deployed contract address can be obtained through a deterministic algorithm, using the following formula:
The pedersen() in the above formula is a hash algorithm that is easy to use in the ZK system. The process of generating an account is actually to give the pedersen function Enter several special parameters to generate the corresponding hash. This hash is the generated account address.
The above picture shows several parameters used by Starknet to generate a "new contract address". deployer_address represents the address of the "contract deployer". This parameter can be empty, even if you do not have Starknet in advance. Contract accounts can also deploy new contracts.
Salt is used to calculate the salt value of the contract address. Simply put, it is a random number. This variable is actually introduced to avoid duplication of contract addresses. class_hash is the hash value of the class corresponding to the contract instance as introduced earlier. And constructor_calldata_hash represents the hash of the contract initialization parameters.
Based on the above formula, users can pre-calculate the generated contract address before the contract is deployed on the chain. Starknet allows users to directly deploy contracts without having a Starknet account in advance. The process is as follows:
1. The user first determines the contract instance he wants to deploy, which contract class he wants to associate with it, and uses the hash of the class as Initialize one of the parameters, calculate the salt, and learn the contract address you generated;
2. After the user knows where he will deploy the contract, he first transfers a certain amount of ETH to the address as Contract deployment fees. Generally speaking, this part of ETH needs to be crossed from L1 to the Starknet network through a cross-chain bridge;
3. The user initiates a transaction request for contract deployment.
In fact, all Starknet accounts are deployed through the above process, but most wallets shield the details, and users cannot perceive the process at all, as if After you transfer ETH yourself, the contract account will be deployed.
The above solution brings some compatibility issues because different wallets are generating When entering account addresses, the generated results are inconsistent. Only wallets that meet the following conditions can be mixed:
The private key derived public key used by the wallet is the same as the signature algorithm;
The salt calculation process of the wallet is the same;
- < p>The smart contract classes of the wallet are not fundamentally different in implementation details;
In the cases mentioned before, both Argent and Braavos used the ECDSA signature algorithm, but The salt calculation methods of both parties are different, and the account addresses generated by the same mnemonic phrase in the two wallets will be inconsistent.
Let’s return to the topic of account abstraction. Starknet and zkSync Era have moved a series of processes involved in the transaction processing process, such as identity verification (verification of digital signatures), gas fee payment and other core logic, to be implemented outside the "bottom layer of the chain". Users can customize the implementation details of the above logic in their own accounts.
For example, you can deploy a dedicated digital signature verification function in your own Starknet smart contract account, When the Starknet node receives the transaction initiated by you, it will call a series of transaction processing logic customized by you in the account on the chain. This is obviously more flexible.
In the design of Ethereum, logic such as identity verification (digital signature) is hard-coded in the node client code and cannot natively support the customization of account functions.
(Schematic diagram of the native AA solution specified by the Starknet architect. Transaction verification and gas fee qualification verification are transferred to the on-chain contract for processing. The underlying virtual machine of the chain can call these user-defined or specified functions. )
According to zkSyncEra and Starknet officials, this set of account function modularization ideas is based on EIP-4337. But the difference is that zkSync and Starknet have merged account types from the beginning, unified transaction types, and used a unified entrance to receive and process all transactions. Ethereum has historical baggage and the foundation We hope to avoid rough iterative plans such as hard forks as much as possible, so we support the "curve to save the country" plan such as EIP-4337. However, the effect is that the EOA account and the 4337 plan each adopt independent transaction processing processes. , looks awkward and bloated, not as flexible as native AA.
(Image source: ArgentWallet)
However, Starknet’s native account abstraction has not yet reached complete maturity. Judging from practical progress , Starknet’s AA account has implemented the customization of the signature verification algorithm, but for the customization of handling fee payment, currently Starknet only supports ETH and STRK to pay gas fees, and does not yet support third-party gas payment. Therefore, Starknet's progress on native AA can be said to be"The theoretical solution is basically mature, and the practical solution is still advancing."
Since there are only smart contract accounts in Starknet, the impact of the account smart contract is considered in the entire transaction process. First, after a transaction is received by the Starknet node's memory pool (Mempool), it must be verified. The verification steps include:
-
Whether the digital signature of the transaction is correct, the custom signature verification function in the transaction initiator's account will be called;
Can the transaction initiator's account balance be paid? Afford the gas fee;
It should be noted here that using the customized signature verification function in the account smart contract means there is an attack scenario. Because the memory pool does not charge gas fees when verifying signatures of new transactions (if gas fees are charged directly, it will lead to more serious attack scenarios). Malicious users can first customize a super complex signature verification function in their account contract, and then initiate a large number of transactions. When these transactions are verified, they will call the customized complex signature verification function, which can directly exhaust the node's power. Computing resources.
In order to avoid this situation, StarkNet has imposed the following restrictions on transactions:
There is an upper limit on the number of transactions that a single user can initiate within a unit of time;
The custom signature verification function in the Starknet account contract is complex. Due to the above restrictions, overly complex signature verification functions will not be executed. Starknet limits the gas consumption limit of the signature verification function. If the amount of gas consumed by the signature verification function is too high, the transaction will be directly rejected. At the same time, the signature verification function in the account contract is not allowed to call other contracts.
The flow chart of Starknet transactions is as follows:
It is worth noting that in order to further speed up the transaction verification process, the signature verification algorithms of Braavos and Argent wallets are directly implemented in the Starknet node client, When a node discovers that a transaction is generated from these two mainstream Starknet wallets, it will call the Braavos/Argent signature algorithm that comes with the client. Through this caching-like idea, Starknet can shorten the transaction verification time.
After the transaction data passes the verification of the sorter (the verification steps of the sorter are much deeper than the memory pool verification), the sorter will package the transactions from the memory pool and submit them to the ZK certificate generator . Even if the transaction entering this link fails, gas will be charged.
But if readers understand the history of Starknet, they will find that the early Starknet did not charge handling fees for failed transactions. The most common transaction failure situation is that the user only has 1ETH. funds, but transferring 10 ETH out. This transaction obviously has a logical error and will eventually fail, but no one knows what the result will be before it is executed.
But StarkNet did not charge fees for such failed transactions in the past. This costless erroneous transaction will waste the computing resources of Starknet nodes and lead to DDoS attack scenarios. On the surface, charging fees for erroneous transactions seems easy to implement, but in fact it is quite complicated. Starknet launched a new version of the Cairo1 language, largely to solve the problem of gas collection for failed transactions.
We all know that ZK Proof is a proof of validity, and the result of a failed transaction is invalid and cannot leave an output result on the chain. Trying to use validity proof to prove that a certain instruction is invalid and cannot produce an output result sounds quite strange, but is actually not feasible. Therefore, in the past, when Starknet generated proofs, it directly eliminated all failed transactions that could not produce output results.
The Starknet team later adopted a smarter solution and built a new contract language Cairo1 so that "all transaction instructions can produce output results and be onchain." At first glance, all transactions can produce output, which means that there are never logical errors. Most of the time, transactions fail because some bugs are encountered, which interrupts the execution of instructions.
It is difficult to achieve a transaction that is never interrupted and successfully generates output. However, there is actually a very simple alternative, which is to allow the transaction to generate output results when it encounters a logic error and causes interruption. However, a False value will be returned at this time to let everyone know that the transaction was not executed smoothly.
But it should be noted that returning a False value also returns the output result. In other words, in Cairo1, output can be generated regardless of whether the instruction encounters a logic error or whether there is a temporary interruption. The result is not onchain. This output can be correct, or it can be a False error message.
For Example, if the following code segment exists:
The _balances::read(from)-amount here may report an error due to underflow, which will cause the corresponding transaction instructions to be interrupted and stop executing, and the transaction results will not be left on the chain; and If it is rewritten into the following form, an output result will still be returned when the transaction fails and remains on the chain.From a purely visual point of view, it is as if all transactions can successfully leave transaction output on the chain. It is particularly reasonable to charge a unified handling fee.
StarknetAA Contract Overview h2>
Considering that some readers of this article may have a programming background, here is a brief demonstration of the interface of the account abstract contract in Starknet:
__validate_declare__ in the above interface is used for verification of declare transactions initiated by users, while __validate__ is used for verification of general transactions, mainly verification Whether the user's signature is correct, and __execute__ is used for transaction execution. We can see that Starknet contract accounts support multicall by default. Multiple calls can achieve some very interesting functions, such as packaging the following three transactions when performing certain DeFi interactions:
The first transaction authorizes the token to the DeFi contract
The second transaction triggers the DeFi contract logic
< li>The third transaction clears the authorization for the DeFi contract
Of course, since multiple calls are atomic, there are some more complex usages, such as Execute certain arbitrage trades.
Summary
Starknet The most important technical features include Cairo language that facilitates ZK proof generation, native-level AA, and smart contract models that are independent of business logic and state storage.
Cairo is a general ZK language that can not only implement smart contracts on Starknet, but also be used to develop more traditional applications. Sierra is introduced as an intermediary in its compilation process. The language allows Cairo to iterate frequently without changing the underlying bytecode, and only needs to transmit changes to the intermediate language; Cairo's standard library also includes many basic data structures required for account abstraction.
Starknet smart contracts store business logic and status data separately. Different from the EVM chain, Cairo contract deployment includes three stages of "compilation, declaration, and deployment", and the business logic is declared In the Contract class, the Contract instance containing state data can be associated with the class and call the code contained in the latter;
The above smart contract model of Starknet is conducive to code reuse. Contract state reuse, storage stratification, and junk contract detection are also conducive to the realization of storage leasing and transaction parallelization. Although the latter two have not yet been implemented, the structure of Cairo smart contracts has created "necessary conditions" for them.
The Starknet chain only has smart contract accounts and no EOA accounts. It supports native-level AA account abstraction from the beginning. Its AA plan absorbs the ideas of ERC-4337 to a certain extent, allowing users to choose highly customized transaction processing solutions. In order to prevent potential attack scenarios, Starknet has taken many countermeasures and made important explorations into the AA ecosystem.