Kakarot RPC fits in the three-part architecture of the Kakarot zkEVM rollup (Kakarot EVM Cairo Programs, Kakarot RPC, Kakarot Indexer). It is the implementation of the Ethereum JSON-RPC specification made to interact with Kakarot zkEVM in a fully Ethereum-compatible way.
The Kakarot RPC layer's goal is to receive and output EVM-compatible payloads & calls while interacting with an underlying StarknetOS client. This enables Kakarot zkEVM to interact with the usual Ethereum tooling: Metamask, Hardhat, Foundry, etc.
Note that this is necessary because Kakarot zkEVM is implemented as a set of Cairo Programs that run on an underlying CairoVM (so-called StarknetOS) chain.
This adapter layer is based on:
Here is a high level overview of the architecture of Kakarot RPC.
Below is a lower level detailed overview of the internal architecture.
TL;DR:
make setup
to build dependencies.cargo build
to build Kakarot RPC.make test
.make run-dev
(you'll need a StarknetOS instance running in another process and Kakarot contracts deployed)make local-rpc-up
make docker-down
make docker-build
Makefile
for running commands such as building the project or executing tests.To set up the repository (pulling git submodule and building Cairo dependencies), run:
make setup
Caveats:
setup
make command uses linux (MacOs compatible) commands to allow
running the ./scripts/extract_abi.sh
. This script is used to use strongly
typed Rust bindings for Cairo programs. If you encounter problems when building
the project, try running ./scripts/extract_abi.sh
.To build the project from source (in release mode):
cargo build --release
Note that there are sometimes issues with some dependencies (notably scarb or cairo related packages, there are sometimes needs to cargo clean
and cargo build
)
Copy the .env.example
file to a .env
file and populate each variable
cp .env.example .env
Meanwhile you can just use unit tests to dev.
make test
The binaries will be located in target/release/
.
To run a local Starknet sequencer, you can use Katana. Katana, developed by the Dojo team, is a sequencer designed to aid in local development. It allows you to perform all Starknet-related activities in a local environment, making it an efficient platform for development and testing. To run Katana and deploy the Kakarot zkEVM (a set of Cairo smart contracts implementing the EVM):
make run-katana
This command will install Katana and generate a genesis file at .katana/genesis.json
. Katana's genesis configuration feature is a way to define the initial state and settings of the Kakarot blockchain network locally, providing a customizable starting point for the chain. Among other things, it allows you to:
To deploy Kakarot Core EVM (set of Cairo Programs):
make deploy-kakarot
To run the Kakarot RPC pointing to this local devnet:
STARKNET_NETWORK=katana make run-dev
Some notes on this local devnet:
this will run a devnet by running katana, with contracts automatically
deployed, so you don't have to do them manually (see in ./lib/kakarot/kakarot_scripts/deploy_kakarot.py
for the list of contracts).
the deployments and declarations for the devnet will be written to the
deployments/katana
folder inside your project root after a successful run of
the make deploy-kakarot
command.
In order to build a Docker Image for the RPC, you can run the below command which will setup the local environment and compile the binary:
make docker-build
An example script to run which uses a pre-funded EOA account with private key
EVM_PRIVATE_KEY
forge script scripts/PlainOpcodes.s.sol --broadcast --legacy --slow
Kakarot RPC is configurable through environment variables.
Check out .env.example
file to see the environment variables.
This section outlines how to run a complete node in different environments: local, staging, and production. Running a node involves several critical components to ensure the system operates effectively:
By correctly configuring these components, you can ensure that the node functions as a robust part of the system.
In the following sections we have tried to provide the most important parameters useful for understanding and configuring the node. However for the sake of brevity, certain parameters deemed less important are omitted and can all be found in the corresponding Docker compose files:
docker-compose.yaml
docker-compose.staging.yaml
docker-compose.prod.yaml
To start the entire infrastructure locally, use the following command:
make local-rpc-up
This command will use the docker-compose.yaml
file to set up the whole infrastructure locally utilizing the following elements:
Katana (local sequencer):
Kakarot EVM Programs:
0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca
.0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a
.0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
.http://starknet:5050
.STARKNET_NETWORK=katana
.Kakarot RPC Node on port 3030:
MONGO_CONNECTION_STRING=mongodb://mongo:mongo@mongo:27017
.MONGO_DATABASE_NAME=kakarot-local
.Apibara Indexer Service on port 7171:
MongoDB with Mongo Express on port 27017 for data management.
To start the entire infrastructure in the staging environment, use the following command:
make staging-rpc-up
This command will use the docker-compose.staging.yaml
file to set up the whole infrastructure in the staging configuration utilizing the following elements:
Starknet Full-Node (Juno) on port 6060:
ETH_NODE_WS
(for example ETH_NODE_WS=wss://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY
).KKRT_BETA
.https://gateway-beta.kakarot.sw-dev.io/feeder_gateway/
.https://gateway-beta.kakarot.sw-dev.io/gateway/
.11155111
(Ethereum Sepolia).kkrt
.0xc7c9ea7fD0921Cb6EDd9a3184F88cF1b821aA82B
.0
to 0
.Starknet Explorer on port 4000:
Starknet Explorer Database (Postgres) on port 5432.
Kakarot RPC Node on port 3030:
http://starknet:6060
.mongodb://mongo:mongo@mongo:27017
.kakarot-local
.0x2824d6ed6759ac4c4a54a39b78d04c0e48be8937237026bf8c3bf46a8bea722
.0x600f6862938312a05a0cfecba0dcaf37693efc9e4075a6adfb62e196022678e
.Apibara DNA Indexer Service on port 7171:
MongoDB with Mongo Express on port 27017 for data management.
To start the entire infrastructure in the production environment, use the following command:
make testnet-rpc-up
This command will use the docker-compose.prod.yaml
file to set up the whole infrastructure in the production configuration utilizing the following elements:
Starknet Full-Node (Juno) on port 6060:
ETH_NODE_WS
(for example ETH_NODE_WS=wss://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY
).kakarot-sepolia
.https://gateway.kakarot.sw-dev.io/feeder_gateway/
.https://gateway.kakarot.sw-dev.io/gateway/
.11155111
(Ethereum Sepolia).kkrt
.0x74Ca1aC5BD4c3c97006d2B7b9375Dd3B6C17ACcD
.0
to 1000000
.Starknet Explorer on port 4000:
Starknet Explorer Database (Postgres) on port 5432.
Kakarot RPC Node on port 3030:
http://starknet:6060
.mongodb://mongo:mongo@mongo:27017
.kakarot-local
.0x11c5faab8a76b3caff6e243b8d13059a7fb723a0ca12bbaadde95fb9e501bda
.0x600f6862938312a05a0cfecba0dcaf37693efc9e4075a6adfb62e196022678e
.0x1276d0b017701646f8646b69de6c3b3584edce71879678a679f28c07a9971cf
.Apibara DNA Indexer Service on port 7171:
MongoDB with Mongo Express on port 27017 for data management.
When setting up the Kakarot node in any environment, it's important to be aware of the following:
You can take a look at rpc-call-examples
directory. Please note the following:
sendRawTransaction.hurl
: the raw transaction provided allows to call the
inc()
function for the Counter contract. However, given that this
transaction is signed for the EOA's nonce at the current devnet state (0x2),
the call will only work once. If you want to keep incrementing (or
decrementing) the counter, you need to regenerate the payload for the call
with an updated nonce using the
provided python script.In order to execute the Rust tests, follow the below instructions:
make setup
in order to setup the project.make test
which will create a Genesis test file for Kakarot
and launch tests.make katana-genesis
once, then run make test-target TARGET=test_you_want_to_run
.In order to run the Typescript unit tests, you will need to have Deno
installed. Then you can run KAKAROT_ADDRESS=ADDRESS_YOU_WANT_TO_USE_FOR_KAKAROT deno test --allow-env
.
The Hive end-to-end test suite is set up in the Github Continuous Integration (CI) flow of the repository. This ensures a safe guard when modifying the current RPC implementation and/or the execution layer.
Due to the current existing differences between the Kakarot EVM implementation which aims to be a type 2 ZK-EVM (see the blog post from Vitalik for more details), some of the Hive tests need to be skipped or slightly modified in order to pass.
For the hive rpc tests, all the websockets related tests are skipped as websockets aren't currently supported by the Kakarot RPC.
For the hive rpc compatibility tests, the following tests are skipped:
debug_getRawBlock/get-block-n
.reth_primitives::B256
type when
deserializing the hash. This test is expected to fail as the provided hash
in the query doesn't start with 0x
. As this test doesn't bring much, we
decide to skip it.debug_getRawBlock/get-block-n
.debug_getRawBlock/get-block-n
.debug_getRawBlock/get-block-n
.debug_getRawBlock/get-block-n
.debug_getRawBlock/get-block-n
.reth_primitives::U256
type when
deserializing the number. This test is expected to fail as the provided block
number in the query doesn't start with exceeds 32 bytes. As this test doesn't
bring much, we decide to skip it.jsonrpsee
crate's macro rpc
in order to generate the server implementation
of the ETH API. This test passes an invalid block hash 0xasdf
and expects
the server to return with an error code -32000
which corresponds to an
invalid input error. The code derived from the rpc
macro returns an error
code of -32602
which corresponds to an invalid parameters error, whenever
it encounters issues when deserializing the input. We decide to ignore this
test as the only issue is the error code returned.debug_getRawBlock/get-block-n
.In addition to the tests we skip, some of the objects fields need to be ignored in the passing tests:
If you which to run our hive test suite locally, the following steps should be taken:
Set up the repo: make setup
.
Build a local docker image of the RPC. Check the hive Dockerfile
for the values for xxx
and yyy
:
docker build --build-arg APIBARA_STARKNET_BIN_DIR=xxx --build-arg APIBARA_SINK_BIN_DIR=yyy -t hive . -f docker/hive/Dockerfile
Checkout the Kakarot fork of hive: git clone https://github.com/kkrt-labs/hive
Build the hive binary: go build hive.go
Run the full rpc test suite against Kakarot:
./hive --sim "ethereum/rpc" --client kakarot
Additional filtering can be provided using --sim.limit
if you which to run
a certain limited set of tests.
If you want to say thank you or/and support active development of Kakarot RPC:
First off, thanks for taking the time to contribute! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are greatly appreciated.
Please read our contribution guidelines, and thank you for being involved!
For a full list of all authors and contributors, see the contributors page.
Kakarot RPC follows good practices of security, but 100% security cannot be assured. Kakarot RPC is provided "as is" without any warranty. Use at your own risk.
For more information and to report security issues, please refer to our security documentation.
This project is licensed under the MIT license.
See LICENSE for more information.
We warmly thank all the people who made this project possible.
For now, Kakarot RPC provides a minimal benchmarking methodology. You'll need Bun installed locally.
katana --block-time 6000 --disable-fee
if you have the dojo binary locally,
or make madara-rpc-up
for Madara.make deploy-kakarot
)make run-dev
)make benchmark-katana
or make benchmark-madara
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!