Kakarot 介紹:開發與範例
2024-10-09 09:32
Taipei Ethereum Meetup
2024-10-09 09:32
订阅此专栏
收藏此文章
Author: ChiHaoLu(chihaolu.eth)

Travel Preparations

本文繼前篇 Kakarot 介紹:Overview,會從開發的角度切入繼續介紹 Kakarot 相關內容,包含與 Ethereum 的差異和合約開發範例。在開始之前會希望讀者具備以下基本知識,可以更快掌握專有名詞和技術架構。

Differences between Kakarot and Ethereum

Opcodes

  • 在 Kakarot 中倒數十個區塊的 BLOCKHASH 會回傳 0,需要等待前篇提到的 Blockhash Registry 完成設定。且 Etherum 中 BLOCKHASH 的計算是 keccak256,而 Kakarot 是使用 pedersen。
  • 在 Kakarot 中沒有 Blob 的存在,所以 BLOBBASEFEE 會回傳 1。這個數字是根據 EIP-4844 的 MIN_BASE_FEE_PER_BLOB_GAS 定義。
  • 在 Kakarot 中 BLOBHASH 會回傳 0。

另外,在選擇 evm version 以及 solc version 時請確定當前的鏈支援 PUSH0 或以太坊升級會出現的新 opcodes。目前 Kakarot 是支援的,所以我們可以放心把合約版本設定在 0.8.19 以上和 shanghai。

Precompile

在 Precompile 這個議題可以分成幾個角度:

  • Kakarot 支援 EVM 的 precompile
  • Kakarot 支援 EVM 還不支援的 precompile
  • Kakarot 支援 StarkNet 的 precompile

首先在 EVM Precompile 的支援上,Kakarot 100% 支援 10 個合約中的 7 個,包含:

  • 0x01: ecRecover
  • 0x02: SHA2–256
  • 0x03: RIPEMD-160
  • 0x04: identity
  • 0x06: ecAdd
  • 0x07: ecMul
  • 0x09: blake2f

不支援的是:

  • 0x05: modexp
  • 0x08: ecPairing
  • 0x0a: point evaluation

而 P256 Verification (secp256r1 — RIP-7212) 這個 precompile 在 Ethereum 還不支持,若在 Ethereum 驗證目前還是使用 DAIMO P256 Verifer 為主,但是在 Kakarot 已經可以使用 precompile(0x100)完成驗證。

在 StarkNet 上,我們可以在 Kakarot 合約中呼叫 Cairo precompile(在 0x75001 上)這個合約來呼叫任何 Cairo 合約。由於這部分的使用需要與 Kakarot 官方聯繫,就不擴展篇幅,細節大家可見官方文件

Development Example

Contract Side

這裡我們使用 Kakarot 官方文件沒有提到的 Foundry 來做為範例開發,原始碼的連結在 ChiHaoLu/kakarot-foundry。基本上設定與命令我都已經寫好確定能跑了,大家只要把合約、測試、腳本改成自己的形狀就行(記得檔名改了指令也要記得改)。

在撰寫上和其他 EVM 相容的鏈一樣不能說很像,只能說幾乎一模一樣,我就不把程式碼貼過來佔版面了。在這邊我們測試在 Kakarot 的環境中能不能順利使用 ecrecover(0x01)這個 precompiled 合約。

function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) internal pure returns (address) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);

return ecrecover(_ethSignedMessageHash, v, r, s);
}

在撰寫完合約之後,可以使用 — fork 指令來 fork 測試,參數填上 Kakarot 的 public RPC URL:

$ forge test --fork-url "https://sepolia-rpc.kakarot.org"

部署時依然可以使用同樣的 RPC URL:

$ forge script ./script/SignatureVerifier.s.sol --broadcast --rpc-url "https://sepolia-rpc.kakarot.org"

驗證時則比較麻煩,因為當前 Kakarot 的區塊瀏覽器是使用 Routescan,和 Etherscan 那套不一樣,所以這邊在驗證上我們要自己提供 — verifier-url 為在 Routescan 上驗證的 API URL。另外,當前在 Kakarot Sepolia 驗證不需要申請任何 API KEY,這邊在 key flag 只要給個字串 “kakarot_sepolia” 就行:

$ forge verify-contract 0x99682dAc0D03F0D12392dCE0B0E34f4AaD0b56E1 ./src/SignatureVerifier.sol:SignatureVerifier \
--verifier-url 'https://api.routescan.io/v2/network/testnet/evm/1802203764_2/etherscan' \
--etherscan-api-key "kakarot_sepolia" \
--num-of-optimizations 200 \
--compiler-version "v0.8.26+commit.8a97fa7a"
>
Start verifying contract `0x99682dAc0D03F0D12392dCE0B0E34f4AaD0b56E1` deployed on kakarot-sepolia

Submitting verification for [src/SignatureVerifier.sol:SignatureVerifier] 0x99682dAc0D03F0D12392dCE0B0E34f4AaD0b56E1.
Submitted contract for verification:
Response: `OK`
GUID: `7e88936a-fe91-5599-9ede-cc19ba05dda9`
URL: https://sepolia.kakarotscan.org/address/0x99682dac0d03f0d12392dce0b0e34f4aad0b56e1

請特別注意以下內容皆符合你自己的設定:

  • 合約路徑與名稱
  • 合約版本
  • 合約 optimizer

經過以上步驟後,就成功在 Kakarot 上部署並且驗證合約了!

Front-End Side

接下來我們來嘗試用 Metamask 簽岀合法簽章然後在我們剛剛部署的 Kakarot 合約通過驗證。原始碼的連結在 ChiHaoLu/kakarot-dapp。這個專案使用 viem 與 next.js 作為框架,細部程式碼就不貼上來,只講解比較重要的部分。

打開專案 yarn install 然後 yarn dev 即可直接嘗試!

在 viem 中已經有關於 Kakarot Sepolia 的網路資訊,我們就不用再把 RPC URL 等內容自己填上了,直接 import 即可。

import { kakarotSepolia } from "viem/chains";
import {
createWalletClient,
createPublicClient,
custom,
getContract,
Address,
} from "viem";

const handleSignAndVerify = async () =>

// Connect
const publicClient = createPublicClient({
chain: kakarotSepolia,
transport: custom(window.ethereum!),
});
const walletClient = createWalletClient({
chain: kakarotSepolia,
transport: custom(window.ethereum!),
});

// 要求用戶的錢包將網路換為 Kakarot Sepolia
await walletClient.switchChain({ id: kakarotSepolia.id });
const contract = getContract({
address: contractAddress as Address,
abi: SignatureVerifierMetadata.abi,
client: { public: publicClient, wallet: walletClient },
}) as any;

// remaining code...
};

簽章的部分我們 request Metamask 對 messageHash 進行簽名:

const handleSignAndVerify = async () => 
// previous code...

// Sign
const [address] = await walletClient.requestAddresses();
const messageHash = await contract.read.getMessageHash([message])
const signature = await walletClient.signMessage({
account: address,
message: { raw: messageHash },
});

// remaining code...
};

最後可以使用 verify 得到簽章是否合法:

const handleSignAndVerify = async () => 
// previous code...

// Verify
const verifyResult = await contract.read.verify([
address,
message,
signature,
]) as boolean
};

Reference

TEM Medium 2024 有獎徵稿 TEM Medium 目前正在進行有獎徵稿!詳情請參考: https://medium.com/taipei-ethereum-meetup/tem-medium-2024-call-for-article-8412024c2390


Kakarot 介紹:開發與範例 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

Taipei Ethereum Meetup
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开