Skip to content
This repository was archived by the owner on Jan 9, 2025. It is now read-only.

Commit 426e602

Browse files
committed
generic_account -> account_contract
1 parent 7230962 commit 426e602

File tree

19 files changed

+104
-79
lines changed

19 files changed

+104
-79
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ jobs:
168168
uses: actions/checkout@v3
169169
with:
170170
repository: kkrt-labs/ef-tests
171-
ref: refactor/rename-storage-vars
172171
- name: Checkout local skip file
173172
uses: actions/checkout@v3
174173
with:

docs/general/decode_a_cairo_trace.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ from starkware.cairo.lang.vm.reconstruct_traceback import reconstruct_traceback
8989

9090
build_dir = Path("build")
9191
programs = {}
92-
for contract_name in ["uninitialized_account", "kakarot", "generic_account", "EVM"]:
92+
for contract_name in ["uninitialized_account", "kakarot", "account_contract", "EVM"]:
9393
artifact = build_dir / f"{contract_name}.json"
9494
if not artifact.is_file():
9595
artifact = build_dir / "fixtures" / f"{contract_name}.json"

kakarot_scripts/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class ArtifactType(Enum):
155155

156156
COMPILED_CONTRACTS = [
157157
{"contract_name": "kakarot", "is_account_contract": False},
158-
{"contract_name": "generic_account", "is_account_contract": True},
158+
{"contract_name": "account_contract", "is_account_contract": True},
159159
{"contract_name": "uninitialized_account", "is_account_contract": False},
160160
{"contract_name": "EVM", "is_account_contract": False},
161161
{"contract_name": "OpenzeppelinAccount", "is_account_contract": True},
@@ -164,7 +164,7 @@ class ArtifactType(Enum):
164164
]
165165
DECLARED_CONTRACTS = [
166166
{"contract_name": "kakarot", "cairo_version": ArtifactType.cairo0},
167-
{"contract_name": "generic_account", "cairo_version": ArtifactType.cairo0},
167+
{"contract_name": "account_contract", "cairo_version": ArtifactType.cairo0},
168168
{"contract_name": "uninitialized_account", "cairo_version": ArtifactType.cairo0},
169169
{"contract_name": "EVM", "cairo_version": ArtifactType.cairo0},
170170
{"contract_name": "OpenzeppelinAccount", "cairo_version": ArtifactType.cairo0},

kakarot_scripts/deploy_kakarot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def main():
5656
"kakarot",
5757
account.address, # owner
5858
ETH_TOKEN_ADDRESS, # native_token_address_
59-
class_hash["generic_account"], # generic_account_class_hash_
59+
class_hash["account_contract"], # account_contract_class_hash_
6060
class_hash["uninitialized_account"], # uninitialized_account_class_hash_
6161
class_hash["Precompiles"],
6262
BLOCK_GAS_LIMIT,
@@ -66,7 +66,7 @@ async def main():
6666
deployments["EVM"] = await deploy(
6767
"EVM",
6868
ETH_TOKEN_ADDRESS, # native_token_address_
69-
class_hash["generic_account"], # generic_account_class_hash_
69+
class_hash["account_contract"], # account_contract_class_hash_
7070
class_hash["uninitialized_account"], # uninitialized_account_class_hash_
7171
class_hash["Precompiles"],
7272
BLOCK_GAS_LIMIT,

kakarot_scripts/utils/kakarot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ async def eth_get_code(address: Union[int, str]):
451451
return bytes(
452452
(
453453
await _call_starknet(
454-
"generic_account", "bytecode", address=starknet_address
454+
"account_contract", "bytecode", address=starknet_address
455455
)
456456
).bytecode
457457
)

src/backend/starknet.cairo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ from kakarot.model import model
2828
from kakarot.state import State
2929
from kakarot.storages import (
3030
Kakarot_native_token_address,
31-
Kakarot_generic_account_class_hash,
31+
Kakarot_account_contract_class_hash,
3232
Kakarot_uninitialized_account_class_hash,
3333
Kakarot_evm_to_starknet_address,
3434
Kakarot_coinbase,
@@ -86,7 +86,7 @@ namespace Starknet {
8686
);
8787

8888
// Properly initialize the account once created
89-
let (account_class_hash) = Kakarot_generic_account_class_hash.read();
89+
let (account_class_hash) = Kakarot_account_contract_class_hash.read();
9090
IUninitializedAccount.initialize(starknet_address, account_class_hash);
9191

9292
evm_contract_deployed.emit(evm_address, starknet_address);

src/kakarot/account.cairo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ from kakarot.constants import Constants
2626
from kakarot.storages import (
2727
Kakarot_uninitialized_account_class_hash,
2828
Kakarot_native_token_address,
29-
Kakarot_generic_account_class_hash,
29+
Kakarot_account_contract_class_hash,
3030
)
3131
from kakarot.interfaces.interfaces import IAccount, IERC20
3232
from kakarot.model import model
@@ -630,7 +630,7 @@ namespace Account {
630630
namespace Internals {
631631
// @notice Compute the storage address of the given key when the storage var interface is
632632
// Account_storage(key: Uint256)
633-
// @dev Just the generated addr method when compiling the generic_account
633+
// @dev Just the generated addr method when compiling the account_contract
634634
func _storage_addr{pedersen_ptr: HashBuiltin*, range_check_ptr}(key: Uint256*) -> (res: felt) {
635635
let res = 0x0127c52d6fa812547d8a5b435341b8c12e82048913e7193c0e318e8a6642876d;
636636
let (res) = hash2{hash_ptr=pedersen_ptr}(res, cast(key, felt*)[0]);

src/kakarot/accounts/generic_account.cairo renamed to src/kakarot/accounts/account_contract.cairo

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin, S
88
from starkware.cairo.common.uint256 import Uint256
99

1010
// Local dependencies
11-
from kakarot.accounts.library import GenericAccount
11+
from kakarot.accounts.library import AccountContract
1212
from starkware.starknet.common.syscalls import get_tx_info, get_caller_address
1313
from starkware.cairo.common.math import assert_le, unsigned_div_rem
1414
from starkware.cairo.common.alloc import alloc
@@ -31,8 +31,8 @@ func constructor{
3131
@external
3232
func initialize{
3333
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
34-
}(kakarot_address: felt, evm_address: felt, implementation_class: felt) {
35-
return GenericAccount.initialize(kakarot_address, evm_address, implementation_class);
34+
}(implementation_class: felt) {
35+
return AccountContract.initialize(implementation_class);
3636
}
3737

3838
// @notice replaces the class of the account.
@@ -41,7 +41,7 @@ func initialize{
4141
func upgrade{
4242
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
4343
}(new_class: felt) {
44-
return GenericAccount.upgrade(new_class);
44+
return AccountContract.upgrade(new_class);
4545
}
4646

4747
// @notice Gets the evm address associated with the account.
@@ -50,7 +50,7 @@ func upgrade{
5050
func get_evm_address{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (
5151
address: felt
5252
) {
53-
return GenericAccount.get_evm_address();
53+
return AccountContract.get_evm_address();
5454
}
5555

5656
// @notice Checks if the account was initialized.
@@ -59,7 +59,7 @@ func get_evm_address{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check
5959
func is_initialized{
6060
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
6161
}() -> (is_initialized: felt) {
62-
return GenericAccount.is_initialized();
62+
return AccountContract.is_initialized();
6363
}
6464

6565
// EOA specific entrypoints
@@ -74,9 +74,12 @@ func is_initialized{
7474
func __validate__{
7575
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, bitwise_ptr: BitwiseBuiltin*, range_check_ptr
7676
}(
77-
call_array_len: felt, call_array: GenericAccount.CallArray*, calldata_len: felt, calldata: felt*
77+
call_array_len: felt,
78+
call_array: AccountContract.CallArray*,
79+
calldata_len: felt,
80+
calldata: felt*,
7881
) {
79-
GenericAccount.validate(
82+
AccountContract.validate(
8083
call_array_len=call_array_len,
8184
call_array=call_array,
8285
calldata_len=calldata_len,
@@ -114,7 +117,10 @@ func __execute__{
114117
bitwise_ptr: BitwiseBuiltin*,
115118
range_check_ptr,
116119
}(
117-
call_array_len: felt, call_array: GenericAccount.CallArray*, calldata_len: felt, calldata: felt*
120+
call_array_len: felt,
121+
call_array: AccountContract.CallArray*,
122+
calldata_len: felt,
123+
calldata: felt*,
118124
) -> (response_len: felt, response: felt*) {
119125
alloc_locals;
120126
let (tx_info) = get_tx_info();
@@ -128,8 +134,12 @@ func __execute__{
128134
assert caller = 0;
129135
}
130136

137+
with_attr error_message("EOA: multicall not supported") {
138+
assert call_array_len = 1;
139+
}
140+
131141
let (local response: felt*) = alloc();
132-
let (response_len) = GenericAccount.execute(
142+
let (response_len) = AccountContract.execute(
133143
call_array_len=call_array_len,
134144
call_array=call_array,
135145
calldata_len=calldata_len,
@@ -146,7 +156,7 @@ func __execute__{
146156
func write_bytecode{
147157
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
148158
}(bytecode_len: felt, bytecode: felt*) {
149-
return GenericAccount.write_bytecode(bytecode_len, bytecode);
159+
return AccountContract.write_bytecode(bytecode_len, bytecode);
150160
}
151161

152162
// @notice This function is used to get the bytecode of the smart contract.
@@ -156,7 +166,7 @@ func write_bytecode{
156166
func bytecode{
157167
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
158168
}() -> (bytecode_len: felt, bytecode: felt*) {
159-
return GenericAccount.bytecode();
169+
return AccountContract.bytecode();
160170
}
161171

162172
// @notice This function is used to get only the bytecode_len of the smart contract.
@@ -166,7 +176,7 @@ func bytecode{
166176
func bytecode_len{
167177
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
168178
}() -> (len: felt) {
169-
let (len) = GenericAccount.bytecode_len();
179+
let (len) = AccountContract.bytecode_len();
170180
return (len=len);
171181
}
172182

@@ -177,7 +187,7 @@ func bytecode_len{
177187
func write_storage{
178188
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
179189
}(storage_addr: felt, value: Uint256) {
180-
return GenericAccount.write_storage(storage_addr, value);
190+
return AccountContract.write_storage(storage_addr, value);
181191
}
182192

183193
// @notice Read a given storage key
@@ -187,18 +197,18 @@ func write_storage{
187197
func storage{
188198
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, bitwise_ptr: BitwiseBuiltin*
189199
}(storage_addr: felt) -> (value: Uint256) {
190-
return GenericAccount.storage(storage_addr);
200+
return AccountContract.storage(storage_addr);
191201
}
192202

193203
// @notice This function is used to read the nonce from storage
194204
// @return nonce The current nonce of the contract account
195205
@view
196206
func get_nonce{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (nonce: felt) {
197-
return GenericAccount.get_nonce();
207+
return AccountContract.get_nonce();
198208
}
199209

200210
// @notice This function set the contract account nonce
201211
@external
202212
func set_nonce{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(nonce: felt) {
203-
return GenericAccount.set_nonce(nonce);
213+
return AccountContract.set_nonce(nonce);
204214
}

src/kakarot/accounts/library.cairo

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ from starkware.starknet.common.syscalls import (
2525
)
2626
from starkware.cairo.common.memset import memset
2727

28+
from kakarot.accounts.shared_storage import Account_evm_address, Account_kakarot_address
2829
from kakarot.interfaces.interfaces import IERC20, IKakarot
2930
from kakarot.errors import Errors
3031
from kakarot.constants import Constants
@@ -43,10 +44,6 @@ func Account_storage(key: Uint256) -> (value: Uint256) {
4344
func Account_is_initialized() -> (res: felt) {
4445
}
4546

46-
@storage_var
47-
func Account_evm_address() -> (evm_address: felt) {
48-
}
49-
5047
@storage_var
5148
func Account_nonce() -> (nonce: felt) {
5249
}
@@ -64,16 +61,21 @@ const BYTES_PER_FELT = 31;
6461
// @title Account main library file.
6562
// @notice This file contains the EVM account representation logic.
6663
// @dev: Both EOAs and Contract Accounts are represented by this contract.
67-
namespace GenericAccount {
64+
namespace AccountContract {
6865
// @notice This function is used to initialize the smart contract account.
66+
// @dev The `evm_address` and `kakarot_address` were set during the uninitialized_account creation.
67+
// Reading them from state ensures that they always match the ones the account was created for.
6968
func initialize{
7069
syscall_ptr: felt*,
7170
pedersen_ptr: HashBuiltin*,
7271
range_check_ptr,
7372
bitwise_ptr: BitwiseBuiltin*,
74-
}(kakarot_address: felt, evm_address: felt, implementation_class: felt) {
73+
}(implementation_class: felt) {
74+
alloc_locals;
7575
let (is_initialized) = Account_is_initialized.read();
7676
assert is_initialized = 0;
77+
let (kakarot_address) = Account_kakarot_address.read();
78+
let (evm_address) = Account_evm_address.read();
7779
Account_is_initialized.write(1);
7880
Ownable.initializer(kakarot_address);
7981
Account_evm_address.write(evm_address);
@@ -229,6 +231,22 @@ namespace GenericAccount {
229231

230232
let tx = EthTransaction.decode([call_array].data_len, calldata + [call_array].data_offset);
231233

234+
// No matter the status of the execution in EVM terms (success - failure - rejected), the nonce of the
235+
// transaction sender must be incremented, as the protocol nonce is. While we use the protocol nonce for the
236+
// transaction validation, we don't make the distinction between CAs and EOAs in their
237+
// Starknet contract representation. As such, the stored nonce of an EOA account must always match the
238+
// protocol nonce, increased by one right before each transaction execution.
239+
//
240+
// In the official specification, this nonce increment is done right after the tx validation checks.
241+
// Since we can only perform these checks in __execute__, which increments the protocol nonce by one,
242+
// we need to increment the stored nonce here as well.
243+
//
244+
// The protocol nonce is updated once per __execute__ call, while the EVM nonce is updated once per
245+
// transaction. If we were to execute more than one transaction in a single __execute__ call, we would
246+
// need to change the nonce incrementation logic.
247+
let (current_nonce) = Account_nonce.read();
248+
Account_nonce.write(current_nonce + 1);
249+
232250
let (kakarot_address) = Ownable_owner.read();
233251
let (block_gas_limit) = IKakarot.get_block_gas_limit(kakarot_address);
234252
let tx_gas_fits_in_block = is_le(tx.gas_limit, block_gas_limit);
@@ -303,14 +321,6 @@ namespace GenericAccount {
303321
response_len=return_data_len, response=return_data, success=success, gas_used=gas_used
304322
);
305323

306-
// No matter the status of the execution (success - failure - rejected), the nonce of the
307-
// transaction sender must be incremented. While we use the protocol nonce for the
308-
// transaction validation, we don't make the distinction between CAs and EOAs in their
309-
// Starknet contract representation. As such, the stored nonce of an EOA account must be
310-
// increased by one after each execution.
311-
let (current_nonce) = Account_nonce.read();
312-
Account_nonce.write(current_nonce + 1);
313-
314324
let (response_len) = execute(
315325
call_array_len - 1,
316326
call_array + CallArray.SIZE,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
%lang starknet
2+
3+
// We are intentionally causing a storage_slot collision here,
4+
// by importing these variables in both `uninitialized_account` and `account_contract`.
5+
// We are defining them here instead of in the account library, so as to not depend
6+
// on content of the account library in uninitialized_account and ensure a fixed class hash.
7+
@storage_var
8+
func Account_evm_address() -> (evm_address: felt) {
9+
}
10+
11+
@storage_var
12+
func Account_kakarot_address() -> (kakarot_address: felt) {
13+
}

0 commit comments

Comments
 (0)