|
9 | 9 | encode_transaction,
|
10 | 10 | serializable_unsigned_transaction_from_dict,
|
11 | 11 | )
|
| 12 | +from eth_account.typed_transactions.set_code_transaction import Authorization as EthAcctAuth |
12 | 13 | from eth_pydantic_types import HexBytes
|
13 |
| -from eth_utils import decode_hex, encode_hex, keccak, to_hex, to_int |
| 14 | +from eth_utils import decode_hex, encode_hex, keccak, to_canonical_address, to_hex, to_int |
14 | 15 | from ethpm_types.abi import EventABI, MethodABI
|
15 |
| -from pydantic import BaseModel, Field, field_validator, model_validator |
| 16 | +from pydantic import BaseModel, Field, field_serializer, field_validator, model_validator |
16 | 17 |
|
17 | 18 | from ape.api.transactions import ReceiptAPI, TransactionAPI
|
18 | 19 | from ape.exceptions import OutOfGasError, SignatureError, TransactionError
|
19 | 20 | from ape.logging import logger
|
20 | 21 | from ape.types.address import AddressType
|
21 | 22 | from ape.types.basic import HexInt
|
22 | 23 | from ape.types.events import ContractLog, ContractLogContainer
|
| 24 | +from ape.types.signatures import MessageSignature |
23 | 25 | from ape.types.trace import SourceTraceback
|
24 | 26 | from ape.utils.misc import ZERO_ADDRESS
|
25 | 27 | from ape_ethereum.trace import Trace, _events_to_trees
|
@@ -55,6 +57,7 @@ class TransactionType(Enum):
|
55 | 57 | ACCESS_LIST = 1 # EIP-2930
|
56 | 58 | DYNAMIC = 2 # EIP-1559
|
57 | 59 | SHARED_BLOB = 3 # EIP-4844
|
| 60 | + SET_CODE = 4 # EIP-7702 |
58 | 61 |
|
59 | 62 |
|
60 | 63 | class AccessList(BaseModel):
|
@@ -97,6 +100,17 @@ def serialize_transaction(self) -> bytes:
|
97 | 100 |
|
98 | 101 | txn_data["accessList"] = adjusted_access_list
|
99 | 102 |
|
| 103 | + if "authorizationList" in txn_data: |
| 104 | + adjusted_auth_list = [] |
| 105 | + |
| 106 | + for item in txn_data["authorizationList"]: |
| 107 | + adjusted_item = { |
| 108 | + k: to_hex(v) if isinstance(v, bytes) else v for k, v in item.items() |
| 109 | + } |
| 110 | + adjusted_auth_list.append(adjusted_item) |
| 111 | + |
| 112 | + txn_data["authorizationList"] = adjusted_auth_list |
| 113 | + |
100 | 114 | unsigned_txn = serializable_unsigned_transaction_from_dict(txn_data)
|
101 | 115 | signature = (self.signature.v, to_int(self.signature.r), to_int(self.signature.s))
|
102 | 116 | signed_txn = encode_transaction(unsigned_txn, signature)
|
@@ -186,6 +200,47 @@ class SharedBlobTransaction(DynamicFeeTransaction):
|
186 | 200 | """
|
187 | 201 |
|
188 | 202 |
|
| 203 | +class Authorization(BaseModel): |
| 204 | + """ |
| 205 | + `EIP-7702 <https://eips.ethereum.org/EIPS/eip-7702>`__ authorization list item. |
| 206 | + """ |
| 207 | + |
| 208 | + chain_id: HexInt = Field(alias="chainId") |
| 209 | + address: AddressType |
| 210 | + nonce: HexInt |
| 211 | + v: HexInt = Field(alias="yParity") |
| 212 | + r: HexBytes |
| 213 | + s: HexBytes |
| 214 | + |
| 215 | + @field_serializer("chain_id", "nonce", "v") |
| 216 | + def convert_int_to_hex(self, value: int) -> str: |
| 217 | + return to_hex(value) |
| 218 | + |
| 219 | + @property |
| 220 | + def signature(self) -> MessageSignature: |
| 221 | + return MessageSignature(v=self.v, r=self.r, s=self.s) |
| 222 | + |
| 223 | + @cached_property |
| 224 | + def authority(self) -> AddressType: |
| 225 | + auth = EthAcctAuth(self.chain_id, to_canonical_address(self.address), self.nonce) |
| 226 | + return EthAccount._recover_hash( |
| 227 | + auth.hash(), |
| 228 | + vrs=(self.signature.v, to_int(self.r), to_int(self.s)), |
| 229 | + ) |
| 230 | + |
| 231 | + |
| 232 | +class SetCodeTransaction(DynamicFeeTransaction): |
| 233 | + """ |
| 234 | + `EIP-7702 <https://eips.ethereum.org/EIPS/eip-7702>`__ transactions. |
| 235 | + """ |
| 236 | + |
| 237 | + authorizations: list[Authorization] = Field(default_factory=list, alias="authorizationList") |
| 238 | + receiver: AddressType = Field(default=ZERO_ADDRESS, alias="to") |
| 239 | + """ |
| 240 | + Overridden because EIP-7702 states it cannot be nil. |
| 241 | + """ |
| 242 | + |
| 243 | + |
189 | 244 | class Receipt(ReceiptAPI):
|
190 | 245 | gas_limit: HexInt
|
191 | 246 | gas_price: HexInt
|
|
0 commit comments