/starknet-accounts-cairo1

Learn how to build and deploy StarkNet Accounts with Cairo v1

Primary LanguageCairo

StarkNet Account Abstraction


Welcome! This is an automated workshop that will explain what account Abstraction is and how you can leverage it to create powerful custom acounts contracts.

Introduction

YOU ARE ON THE ANSWERS BRANCH - PLEASE CHECKOUT start-here

Disclaimer

​ Don't expect any kind of benefit from using this, other than learning a bunch of cool stuff about StarkNet, the first general purpose validity rollup on the Ethereum Mainnnet. ​ StarkNet is still in Alpha. This means that development is ongoing, and the paint is not dry everywhere. Things will get better, and in the meanwhile, we make things work with a bit of duct tape here and there! ​

How it works

TL;DR: accounts on StarkNet are simply regular smart contracts. One caveat is that they MUST have canonical entrypoint denoted with the selectors:

  • __validate__
  • __validate_declare__
  • __execute__

Your goal is to design account contracts that pass all the evaluator.cairo checks and collect all the points available on StarkNet(Goerli).

This tutorial consists of various StarkNet account contracts and starknet_py helper scripts for compilation, deployment, and testing. It also includes an evaluator smart contract, that will check that the code you write in your account contract is correct.

To understand what is expected of you, execute the specified python script for each exercise and read the mission statement that will appear in your terminal. The exercises will get more difficult and will require you to:

  • manipulate the python files
  • write the relevant Cairo code.

These tasks will be annotated with the comment # ACTION ITEM <NUM>

Where am I?

This workshop is the sixth in a series aimed at teaching how to build on StarkNet. Checkout out the following:

Topic GitHub repo
Learn how to read Cairo code Cairo 101
Deploy and customize an ERC721 NFT StarkNet ERC721
Deploy and customize an ERC20 token StarkNet ERC20
Build a cross layer application StarkNet messaging bridge
Debug your Cairo contracts easily StarkNet debug
Design your own account contract (you are here) StarkNet account abstraction

Providing feedback & getting help

Once you are done working on this tutorial, your feedback would be greatly appreciated!

Please fill out this form to let us know what we can do to make it better.

​ And if you struggle to move forward, do let us know! This workshop is meant to be as accessible as possible; we want to know if it's not the case.

​ Do you have a question? Join our Discord server, register, and join channel #tutorials-support ​ Are you interested in following online workshops about learning how to dev on StarkNet? Subscribe here

Contributing

This project can be made better and will evolve as StarkNet matures. Your contributions are welcome! Here are things that you can do to help:

  • Create a branch with a translation to your language
  • Correct bugs if you find some
  • Add an explanation in the comments of the exercise if you feel it needs more explanation
  • Add exercises showcasing your favorite Cairo feature

Getting ready to work

Step 1 - Clone the repo

git clone https://github.com/starknet-edu/starknet-accounts
cd starknet-accounts

Step 2 - Set up your environment

This tutorial uses the cairo environment, starknet-devnet, and starknet.py.

Install the cairo environment

Set up the environment following these instructions

Install dependencies

pip3 install --upgrade -r requirements.txt

Step 3 - Set up your devnet

Transactions take time to complete on testnet so you should develop and debug locally first.

Let's try it out with the hello/hello.cairo exercise. There are no # ACTION ITEMs that need to be completed for this exercise and we can simply test that it works.

1) init devnet

starknet-devnet

2) deploy evaluator

# NOTE: 
# - you do not have to deploy the validator for `testnet`
# - devnet contract details can be found in `contracts/accounts.json`
python3 contracts/tutorial/evaluator.py

3) deploy/test hello contract

python3 contracts/hello/hello.py

The relevant evaluator contract addresses are saved to the contracts/accounts.json cache. For devnet testing the devnet contracts MUST BE DELETED everytime devnet is restarted. If you would like to disable this constract cache run:

export ACCOUNT_CACHE=false

There were no action items for you to complete so you should see a succesfull PAYDAY!!! response from the devnet evaluator contract.

Step 4 - Deploying to testnet

When deploying to testnet fill out the relevant details in the config.json file under TESTNET_ACCOUNT for your StarkNet account to transfer fees and receive rewards.

Argent-X Example

ADDRESS

  • From the example wallet above you can copy the address(0x0742B5662...6476f8f)
  • Paste the felt representation in the config.json TESTNET_ACCOUNT -> ADDRESS
  • To get the felt represenation you can paste the address in this conversion tool.

PRIVATE

  • Select the three vertical dots to display the wallet options
  • Select Export private key
  • Copy the private key from this screen and paste it in config.json TESTNET_ACCOUNT -> PRIVATE.

PUBLIC

  • Select the three vertical dots to display the wallet options
  • Select View on Voyager
  • From the Voyager Block Explorer select the READ Contract -> IMPLEMENTATION tab
  • Drop down the get_signer selector
  • Select Decimal query
  • Copy the public key from this screen and paste it in config.json TESNET_ACCOUNT -> PUBLIC

Example config.json

Step 5 - Accounting for fees

Accounts on StarkNet must pay fees to cover the L1 footprint of their transaction. So the account details you enter must have Goerli ETH(~0.5 ETH) and can be funded either through the starkgate bridge or StarkNet Faucet.

After you have tested your contract locally you can test on testnet by passing the --testnet flag to the starknet_py script:

python3 hello/hello.py --testnet

Step 6 - Using answers

If you need hints on tutorial solutions you can find them in the answers branch. These will include a pytest for you to run, the completed starknet_py, and the completed cairo contract.

Contracts code and addresses

Contract code Contract on voyager
Points counter ERC20 0x0134b89cfb9735a407c58b1a454c40634b600ab1e5a37d8138015f025cc8af4f
Evaluator 0x01bb626c068310ba990db71f7d51fe999c37053d42470aee35698577a44baec6

Working on the tutorial

Exercise 1 - Hello

Lets deploy and test the simplest account contract we can, hello.cairo:

python3 contracts/hello/hello.py

The job of an account contract is to execute arbitrary business logic on behalf of a sepcific entity. This is why we see a similar argument pattern for most execute functions.

Follow the prompt and collect 100 points.

Exercise 2 - Signatures

Signature 1

Unlike Ethereum EOAs, StarkNet accounts don't have a hard requirement on being managed by a public/private key pair.

Account abstraction cares more about who(i.e. the contract address) rather than how(i.e. the signature).

This leaves the ECDSA signature scheme up to the developer and is typically implemented using the pedersen hash and native Stark curve:

python3 contracts/signature/signature_1.py

The signature_1 contract has no concept of a public/private keypair. All the signing was done "off-chain" and yet with account abstraction we're still able to operate a functioning account with a populated signature field.

Follow the prompt and collect 100 points.

Signature 2 - 200 pts

Let's couple the signing logic more succintly wtih the account:

HINT: we have not yet implemented a nonce

python3 contracts/signature/signature_2.py

Although we are free to populate the signature field how we please, the StarkNet OS has a specific method for hashing transaction data.

Follow the prompt and collect 200 points.

Signature 3 - 300 pts

As StarkNet accounts are simply contracts we can implement any signing mechanism we want. Companies like Web3Auth are using this to create Sign-In architectures using your StarkNet account. JWT token schems are being implemented.

Discussions on novel account architecutres are popping up more and more and it looks to be an increasingly important tool in the developer toolkit.

For an example of a unique account architecture we will build a contract that implements it's signatures scheme with the secp256k1 curve and sha256 instead of our native StarkNet curve:

python3 contracts/signature/signature_3.py

Follow the prompt and collect 300 points.

Exercise 3 - MultiCall

Now that we have implemented the vanilla ECDSA signing mechanisms lets see what account abstraction can really do!

A multicall aggregates the results from multiple contract calls. This reduces the number of seperate API Client or JSON-RPC requests that need to be sent. In addition it acts as an atomic invocation where all values are returned for the same block.

Popular wallet providers like Argent use this design to implement account contracts on StarkNet to accomodate a multicall or a single call with one scheme.

There are many implementations of multicall that allow the caller flexibility in how they distribute and batch their transactions.

Let's implement a multicall account for StarkNet:

python3 contracts/multicall/multicall.py

Follow the prompt and collect 500 points.

Exercise 4 - MultiSig

A multisig or multiple signature wallet allows you to share security accross multiple signinging entities. You can think of them like bank vaults in that they require more than one key to unlock, or in this case authorize a transaction.

The amount of signing keys that belong to the account and the ammount of keys required to authorize a transaction are purely implementation details.

Lets implement a 2/3 multisig account(i.e. 2 signatures are required out of a total 3 signers for a transaction to be executed):

python3 contracts/multisig/multisig.py

Follow the prompt and collect 1000 points.