def get_code(self, address: Address) -> bytes: validate_canonical_address(address, title="Storage Address") try: return self._journaldb[self.get_code_hash(address)] except KeyError: return b""
def set_code(self, address: Address, code: bytes) -> None: validate_canonical_address(address, title="Storage Address") validate_is_bytes(code, title="Code") account = self._get_account(address) code_hash = keccak(code) self._code_storage_emulator[code_hash] = code self._set_account(address, account.copy(code_hash=code_hash))
def delete_account(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") self.delete_code(address) if address in self._storage_emulator: del self._storage_emulator[address] if address in self._account_emulator: del self._account_emulator[address]
def delete_code(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") account = self._get_account(address) code_hash = account.code_hash self._set_account(address, account.copy(code_hash=EMPTY_SHA3)) if code_hash in self._code_storage_emulator: del self._code_storage_emulator[code_hash]
def get_code(self, address: Address) -> bytes: validate_canonical_address(address, title="Storage Address") code_hash = self.get_code_hash(address) if code_hash == EMPTY_SHA3: return b'' elif code_hash in self._code_storage_emulator: return self._code_storage_emulator[code_hash]
def add_log_entry(self, account: Address, topics: Tuple[int, ...], data: bytes) -> None: validate_canonical_address(account, title="Log entry address") for topic in topics: validate_uint256(topic, title="Log entry topic") validate_is_bytes(data, title="Log entry data") self._log_entries.append( (self.transaction_context.get_next_log_counter(), account, topics, data))
def set_storage(self, address: Address, slot: int, value: int) -> None: validate_uint256(value, title="Storage Value") validate_uint256(slot, title="Storage Slot") validate_canonical_address(address, title="Storage Address") if address not in self._storage_emulator: self._storage_emulator[address] = dict() self._storage_emulator[address][slot] = value
def delete_account(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") if address in self._account_cache: del self._account_cache[address] del self._journaltrie[address] self._wipe_storage(address)
def set_storage(self, address: Address, slot: int, value: int) -> None: validate_uint256(value, title="Storage Value") validate_uint256(slot, title="Storage Slot") validate_canonical_address(address, title="Storage Address") account_store = self._get_address_store(address) self._dirty_accounts.add(address) account_store.set(slot, value)
def validate(self) -> None: validate_uint256(self.nonce, title="Transaction.nonce") validate_is_integer(self.gas_price, title="Transaction.gas_price") validate_uint256(self.gas, title="Transaction.gas") if self.to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(self.to, title="Transaction.to") validate_uint256(self.value, title="Transaction.value") validate_is_bytes(self.data, title="Transaction.data") super().validate()
def register_account_for_deletion(self, beneficiary: Address) -> None: validate_canonical_address(beneficiary, title="Self destruct beneficiary address") if self.msg.storage_address in self.accounts_to_delete: raise ValueError( "Invariant. Should be impossible for an account to be " "registered for deletion multiple times") self.accounts_to_delete[self.msg.storage_address] = beneficiary
def get_storage(self, address: Address, slot: int, from_journal: bool = True) -> int: validate_canonical_address(address, title="Storage Address") validate_uint256(slot, title="Storage Slot") account_store = self._get_address_store(address) return account_store.get(slot, from_journal)
def set_code(self, address, code): validate_canonical_address(address, title="Storage Address") validate_is_bytes(code, title="Code") account = self._get_account(address) code_hash = keccak(code) self._journaldb[code_hash] = code self._set_account(address, account.copy(code_hash=code_hash))
def validate(self) -> None: validate_uint256(self.chain_id, title="Transaction.chain_id") validate_uint256(self.nonce, title="Transaction.nonce") validate_uint256(self.gas_price, title="Transaction.gas_price") validate_uint256(self.gas, title="Transaction.gas") if self.to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(self.to, title="Transaction.to") validate_uint256(self.value, title="Transaction.value") validate_is_bytes(self.data, title="Transaction.data") validate_is_transaction_access_list(self.access_list)
def get_code(self, address: Address) -> bytes: validate_canonical_address(address, title="Storage Address") code_hash = self.get_code_hash(address) if code_hash == EMPTY_SHA3: return b'' else: try: return self._journaldb[code_hash] except KeyError: raise MissingBytecode(code_hash) from KeyError
def delete_account(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") # We must wipe the storage first, because if it's the first time we load it, # then we want to load it with the original storage root hash, not the # empty one. (in case of a later revert, we don't want to poison the storage cache) self._wipe_storage(address) if address in self._account_cache: del self._account_cache[address] del self._journaltrie[address]
def get_storage(self, address, slot): validate_canonical_address(address, title="Storage Address") validate_uint256(slot, title="Storage Slot") account = self._get_account(address) storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root)) slot_as_key = pad32(int_to_big_endian(slot)) if slot_as_key in storage: encoded_value = storage[slot_as_key] return rlp.decode(encoded_value, sedes=rlp.sedes.big_endian_int) else: return 0
def set_storage(self, address: Address, slot: int, value: int) -> None: validate_uint256(value, title="Storage Value") validate_uint256(slot, title="Storage Slot") validate_canonical_address(address, title="Storage Address") account = self._get_account(address) storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root)) slot_as_key = pad32(int_to_big_endian(slot)) if value: encoded_value = rlp.encode(value) storage[slot_as_key] = encoded_value else: del storage[slot_as_key] self._set_account(address, account.copy(storage_root=storage.root_hash))
def __init__(self, gas: int, to: Address, sender: Address, value: int, data: BytesOrView, code: bytes, depth: int = 0, create_address: Address = None, code_address: Address = None, should_transfer_value: bool = True, is_static: bool = False) -> None: validate_uint256(gas, title="Message.gas") self.gas: int = gas if to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(to, title="Message.to") self.to = to validate_canonical_address(sender, title="Message.sender") self.sender = sender validate_uint256(value, title="Message.value") self.value = value validate_is_bytes_or_view(data, title="Message.data") self.data = data validate_is_integer(depth, title="Message.depth") validate_gte(depth, minimum=0, title="Message.depth") self.depth = depth validate_is_bytes(code, title="Message.code") self.code = code if create_address is not None: validate_canonical_address(create_address, title="Message.storage_address") self.storage_address = create_address if code_address is not None: validate_canonical_address(code_address, title="Message.code_address") self.code_address = code_address validate_is_boolean(should_transfer_value, title="Message.should_transfer_value") self.should_transfer_value = should_transfer_value validate_is_boolean(is_static, title="Message.is_static") self.is_static = is_static
def get_storage(self, address: Address, slot: int, from_journal: bool = True) -> int: validate_canonical_address(address, title="Storage Address") validate_uint256(slot, title="Storage Slot") if address in self._storage_emulator and slot in self._storage_emulator[ address] or not self._remote: try: return self._storage_emulator[address][slot] except KeyError: return 0 else: result = self._remote.getStorageAt(address, slot, "latest") result = to_int(result.hex()) self.set_storage(address, slot, result) if self.snapshot != None: if address not in self.snapshot["storage"]: self.snapshot["storage"][address] = dict() self.snapshot["storage"][address][slot] = result return result
def validate(self) -> None: validate_uint256(self.nonce, title="Transaction.nonce") validate_uint256(self.gas_price, title="Transaction.gas_price") validate_uint256(self.gas, title="Transaction.gas") if self.to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(self.to, title="Transaction.to") validate_uint256(self.value, title="Transaction.value") validate_is_bytes(self.data, title="Transaction.data") validate_uint256(self.v, title="Transaction.v") validate_uint256(self.r, title="Transaction.r") validate_uint256(self.s, title="Transaction.s") validate_lt_secpk1n(self.r, title="Transaction.r") validate_gte(self.r, minimum=1, title="Transaction.r") validate_lt_secpk1n(self.s, title="Transaction.s") validate_gte(self.s, minimum=1, title="Transaction.s") validate_gte(self.v, minimum=self.v_min, title="Transaction.v") validate_lte(self.v, maximum=self.v_max, title="Transaction.v") super().validate()
def delete_storage(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") account = self._get_account(address) self._set_account(address, account.copy(storage_root=BLANK_ROOT_HASH))
def show_set_storage_dialog(self): set_storage_dialog = QDialog() ui = Ui_set_storage_dialog() ui.setupUi(set_storage_dialog) for addr in self.relevant_addresses.values(): if type(addr) is MyContract: ui.address_cb.addItem(addr.get_readable_address()) le: QLineEdit = ui.address_le cb: QComboBox = ui.address_cb kp = le.keyPressEvent lines = 0 val: QLineEdit = None fl: QFormLayout = ui.formLayout def add_line(e=None): nonlocal lines nonlocal val if val is not None: val.focusInEvent = lambda x: None if lines < 6: slot = QLineEdit() val = QLineEdit() slot.setPlaceholderText("slot") val.setPlaceholderText("value") val.focusInEvent = add_line fl.addRow(slot, val) lines += 1 def le_callback(event): kp(event) if len(le.text()) > 0: ui.select_address_lb.setDisabled(True) ui.address_cb.setDisabled(True) if lines == 0: add_line() else: ui.select_address_lb.setDisabled(False) ui.address_cb.setDisabled(False) def cb_callback(): if cb.currentIndex() != 0: ui.enter_address_lb.setDisabled(True) ui.address_le.setDisabled(True) if lines == 0: add_line() else: ui.enter_address_lb.setDisabled(False) ui.address_le.setDisabled(False) le.keyPressEvent = le_callback cb.currentIndexChanged.connect(cb_callback) set_storage_dialog.show() if set_storage_dialog.exec_() == QDialog.Accepted: self.setting_storage = True if cb.currentIndex() != 0 or len(le.text()) != 0: if cb.isEnabled(): addr = Address(decode_hex(cb.currentText()[2:])) else: parsed = self._parse_string(le.text(), decode_hex, []) addr = Address(parsed) err = False try: validate_canonical_address(addr) except ValidationError: err = True if parsed is None or err: self._refresh_statusbar(le.text() + " is not a valid address") return st = "Successfully set storage values" for i in range(0, fl.count()): slot = fl.itemAt(i, QFormLayout.LabelRole) val = fl.itemAt(i, QFormLayout.FieldRole) if slot is not None and val is not None: slot = slot.widget().text() val = val.widget().text() if slot != "" and val != "": slot = self._parse_string(slot, int, [(operator.ge, [0])]) val = self._parse_string(val, int, [(operator.ge, [0])]) if slot is None or val is None: st = "Could not set at least one slot" continue self.evm_handler.set_storage(addr, slot, val) self.set_storage_signal_cb(addr, hex2(slot), hex2(val)) self._refresh_statusbar(st) self.setting_storage = False
def touch_account(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") account = self._get_account(address) self._set_account(address, account)
def account_exists(self, address: Address) -> bool: validate_canonical_address(address, title="Storage Address") return self._journaltrie.get(address, b'') != b''
def delete_code(self, address: Address) -> None: validate_canonical_address(address, title="Storage Address") account = self._get_account(address) self._set_account(address, account.copy(code_hash=EMPTY_SHA3))
def get_code_hash(self, address: Address) -> Hash32: validate_canonical_address(address, title="Storage Address") account = self._get_account(address) return account.code_hash
def set_nonce(self, address: Address, nonce: int) -> None: validate_canonical_address(address, title="Storage Address") validate_uint256(nonce, title="Nonce") account = self._get_account(address) self._set_account(address, account.copy(nonce=nonce))
def get_nonce(self, address: Address) -> int: validate_canonical_address(address, title="Storage Address") account = self._get_account(address) return account.nonce
def show_set_balance_dialog(self): Dialog = QDialog() dialog_ui = Ui_AddAdressesDialog() dialog_ui.setupUi(Dialog) dialog_ui.comboBox.addItems(units.keys()) current_focus_le = dialog_ui.lineEdit_2 line_ctr: int = 1 def add_line(event): """" Callback function for when a QLineEdit gets focus. Will add new line for adding funds.""" nonlocal dialog_ui nonlocal current_focus_le nonlocal line_ctr if line_ctr == 7: return else: line_ctr += 1 left_le = QLineEdit(dialog_ui.gridLayoutWidget) left_le.setInputMask("") left_le.setText("") left_le.setObjectName("lineEdit_" + str(line_ctr) + "l") dialog_ui.gridLayout.addWidget(left_le, line_ctr, 0, 1, 1) right_le = QLineEdit(dialog_ui.gridLayoutWidget) right_le.setEnabled(True) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( right_le.sizePolicy().hasHeightForWidth()) right_le.setSizePolicy(sizePolicy) right_le.setObjectName("lineEdit_" + str(line_ctr) + "r") right_le.focusInEvent = add_line current_focus_le.focusInEvent = lambda x: None current_focus_le = right_le dialog_ui.gridLayout.addWidget(right_le, line_ctr, 1, 1, 1) comboBox = QComboBox(dialog_ui.gridLayoutWidget) comboBox.setCurrentText("") comboBox.setObjectName("comboBox") comboBox.addItems(units.keys()) _translate = QCoreApplication.translate left_le.setPlaceholderText(_translate("Dialog", "0x1337....")) right_le.setPlaceholderText(_translate("Dialog", "0")) dialog_ui.gridLayoutWidget.setGeometry( QRect(30, 20, 661, 51 + (line_ctr - 1) * 33)) dialog_ui.gridLayout.addWidget(comboBox, line_ctr, 2, 1, 1) dialog_ui.lineEdit_2.focusInEvent = add_line Dialog.setFixedSize(Dialog.size()) Dialog.show() txs = [] if Dialog.exec_() == QDialog.Accepted: for i in range(1, line_ctr + 1): addr = dialog_ui.gridLayout.itemAtPosition( i, 0).widget().text()[2:] val = self._parse_string( dialog_ui.gridLayout.itemAtPosition(i, 1).widget().text(), int, [(operator.ge, [0])]) val = 0 if val is None else val unit = dialog_ui.gridLayout.itemAtPosition( i, 2).widget().currentText() if addr != "": txs.append(MyTransaction(addr, val * int(units.get(unit)))) logger.info( "Add tx to addr {a} with value {v} in unit {u}".format( a=addr, v=val, u=unit)) st = "" for tx in txs: st = "Set balances successfully" try: to = tx.addr.get_typed_address() validate_canonical_address(to) assert tx.val >= 0 self.evm_handler.set_balance(Address(to), tx.val) to = tx.addr.get_readable_address() if self.relevant_addresses[to] is None: self.relevant_addresses[to] = tx.addr self._refresh_relevant_addresses() except (ValidationError, AssertionError, ValueError) as e: st = "Could not set at least one balance" self._refresh_statusbar(st)