Пример #1
0
def test_intercontract_call():
    # Arrange
    cfg.gbl_next_uid = 0

    caller_code = Disassembly("6080604052348015600f57600080fd5b5073deadbeefdeadbeefdeadbeefdeadbeefdeadbeef73ffffffffffffffffffffffffffffffffffffffff166389627e13336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801560be57600080fd5b505af115801560d1573d6000803e3d6000fd5b505050506040513d602081101560e657600080fd5b8101908080519060200190929190505050500000a165627a7a72305820fdb1e90f0d9775c94820e516970e0d41380a94624fa963c556145e8fb645d4c90029")
    caller_address = "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe"

    callee_code = Disassembly("608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806389627e13146044575b600080fd5b348015604f57600080fd5b506082600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506084565b005b8073ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f1935050505015801560e0573d6000803e3d6000fd5b50505600a165627a7a72305820a6b1335d6f994632bc9a7092d0eaa425de3dea05e015af8a94ad70b3969e117a0029")
    callee_address = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"

    caller_account = Account(caller_address, caller_code, contract_name="Caller")
    callee_account = Account(callee_address, callee_code, contract_name="Callee")

    accounts = {
        caller_address: caller_account,
        callee_address: callee_account
    }

    laser = svm.LaserEVM(accounts)

    # Act
    laser.sym_exec(caller_address)

    # Assert
    # Initial node starts in contract caller
    assert len(laser.nodes.keys()) > 0
    assert laser.nodes[0].contract_name == 'Caller'

    # At one point we call into contract callee
    for node in laser.nodes.values():
        if node.contract_name == 'Callee':
            assert len(node.states[0].transaction_stack) > 1
            return

    assert False
Пример #2
0
    def __init__(self,
                 code="",
                 creation_code="",
                 name="Unknown",
                 enable_online_lookup=False):
        """Create a new contract.

        Workaround: We currently do not support compile-time linking.
        Dynamic contract addresses of the format __[contract-name]_____________ are replaced with a generic address
        Apply this for creation_code & code

        :param code:
        :param creation_code:
        :param name:
        :param enable_online_lookup:
        """
        creation_code = re.sub(r"(_{2}.{38})", "aa" * 20, creation_code)
        code = re.sub(r"(_{2}.{38})", "aa" * 20, code)

        self.creation_code = creation_code
        self.name = name
        self.code = code
        self.disassembly = Disassembly(
            code, enable_online_lookup=enable_online_lookup)
        self.creation_disassembly = Disassembly(
            creation_code, enable_online_lookup=enable_online_lookup)
Пример #3
0
def decode(code):
    dis = Disassembly(code)
    asm = dis.get_easm()
    tmp = dict()
    for line in asm.splitlines():
        lst = line.split()
        tmp[lst[0]] = ' '.join(lst[1:])
    return (json.dumps(dis.address_to_function_name), json.dumps(tmp))
def _get_global_state():
    active_account = Account("0x0", code=Disassembly("60606040"))
    passive_account = Account("0x325345346564645654645",
                              code=Disassembly("6060604061626364"))
    environment = Environment(active_account, None, None, None, None, None)
    world_state = WorldState()
    world_state.put_account(active_account)
    world_state.put_account(passive_account)
    return GlobalState(world_state, environment, None,
                       MachineState(gas_limit=8000000))
Пример #5
0
    def __init__(self, code, creation_code="", name="Unknown"):

        self.creation_code = creation_code
        self.name = name

        # Workaround: We currently do not support compile-time linking.
        # Dynamic contract addresses of the format __[contract-name]_____________ are replaced with a generic address

        code = re.sub(r'(_+.*_+)', 'aa' * 20, code)

        self.code = code
        self.disassembly = Disassembly(self.code)
Пример #6
0
    def test_easm_from_solidity_files(self):
        for input_file in TESTDATA_INPUTS.iterdir():
            output_expected = TESTDATA_OUTPUTS_EXPECTED / (input_file.name + ".easm")
            output_current = TESTDATA_OUTPUTS_CURRENT / (input_file.name + ".easm")

            code = input_file.read_text()
            disassembly = Disassembly(code)
            output_current.write_text(disassembly.get_easm())

            if not (output_expected.read_text() == output_current.read_text()):
                self.found_changed_files(input_file, output_expected, output_current)

        self.assert_and_show_changed_files()
Пример #7
0
    def dynld(self, contract_address, dependency_address):

        if not self.contract_loading:
            raise ValueError(
                "Cannot load contract when contract_loading flag is false")

        logging.debug("Dynld at contract " + contract_address + ": " +
                      dependency_address)

        m = re.match(r"^(0x[0-9a-fA-F]{40})$", dependency_address)

        if m:
            dependency_address = m.group(1)

        else:
            return None

        logging.debug("Dependency address: " + dependency_address)

        code = self.eth.eth_getCode(dependency_address)

        if code == "0x":
            return None
        else:
            return Disassembly(code)
Пример #8
0
    def dynld(self, contract_address, dependency_address):
        """

        :param contract_address:
        :param dependency_address:
        :return:
        """
        if not self.contract_loading:
            raise ValueError("Cannot load contract when contract_loading flag is false")

        log.debug("Dynld at contract " + contract_address + ": " + dependency_address)

        # Ensure that dependency_address is the correct length, with 0s prepended as needed.
        dependency_address = (
            "0x" + "0" * (42 - len(dependency_address)) + dependency_address[2:]
        )

        m = re.match(r"^(0x[0-9a-fA-F]{40})$", dependency_address)

        if m:
            dependency_address = m.group(1)

        else:
            return None

        log.debug("Dependency address: " + dependency_address)

        code = self.eth.eth_getCode(dependency_address)

        if code == "0x":
            return None
        else:
            return Disassembly(code)
Пример #9
0
def execute_message_call(
    laser_evm,
    callee_address,
    caller_address,
    origin_address,
    code,
    data,
    gas,
    gas_price,
    value,
):
    """ Executes a message call transaction from all open states """
    open_states = laser_evm.open_states[:]
    del laser_evm.open_states[:]

    for open_world_state in open_states:
        next_transaction_id = get_next_transaction_id()
        transaction = MessageCallTransaction(
            identifier=next_transaction_id,
            world_state=open_world_state,
            callee_account=open_world_state[callee_address],
            caller=caller_address,
            call_data=Calldata(next_transaction_id, data),
            gas_price=gas_price,
            call_value=value,
            origin=origin_address,
            call_data_type=CalldataType.SYMBOLIC,
            code=Disassembly(code),
        )

        _setup_global_state_for_execution(laser_evm, transaction)

    laser_evm.exec()
Пример #10
0
def execute_create():
    global last_state
    global created_contract_account
    if not last_state and not created_contract_account:
        code_raw = []
        for i in range(len(contract_init_code) // 2):
            code_raw.append(int(contract_init_code[2 * i:2 * (i + 1)], 16))
        calldata = ConcreteCalldata(0, code_raw)

        world_state = WorldState()
        account = world_state.create_account(balance=1000000, address=101)
        account.code = Disassembly("60a760006000f000")
        environment = Environment(account, None, calldata, None, None, None)
        og_state = GlobalState(world_state, environment, None,
                               MachineState(gas_limit=8000000))
        og_state.transaction_stack.append(
            (MessageCallTransaction(world_state=WorldState(),
                                    gas_limit=8000000), None))

        laser = LaserEVM()
        states = [og_state]
        last_state = og_state
        for state in states:
            new_states, op_code = laser.execute_state(state)
            last_state = state
            if op_code == "STOP":
                break
            states.extend(new_states)

        created_contract_address = last_state.mstate.stack[-1].value
        created_contract_account = last_state.world_state.accounts[
            created_contract_address]

    return last_state, created_contract_account
Пример #11
0
def test_concrete_call_symbolic_to():
    # arrange
    address = "0x10"

    active_account = Account(address)
    active_account.code = Disassembly("00")
    environment = Environment(active_account, None, None, None, None, None)
    state = GlobalState(None, environment, None)
    state.mstate.memory = ["placeholder", "calldata_bling_0"]

    node = Node("example")
    node.contract_name = "the contract name"
    node.function_name = "the function name"

    to = Variable("calldata_3", VarType.SYMBOLIC)
    meminstart = Variable(1, VarType.CONCRETE)
    call = Call(node, state, None, None, to, None)

    # act
    issues = _concrete_call(call, state, address, meminstart)

    # assert
    issue = issues[0]
    assert issue.address == address
    assert issue.contract == node.contract_name
    assert issue.function == node.function_name
    assert issue.title == "Call data forwarded with delegatecall()"
    assert issue.type == "Informational"
    assert (
        issue.description
        == "This contract forwards its call data via DELEGATECALL in its fallback function."
        " This means that any function in the called contract can be executed."
        " Note that the callee contract will have access to the storage of the "
        "calling contract.\n DELEGATECALL target: calldata_3"
    )
Пример #12
0
def execute_contract_creation(laser_evm,
                              contract_initialization_code,
                              contract_name=None) -> Account:
    """ Executes a contract creation transaction from all open states"""
    # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here
    open_states = laser_evm.open_states[:]
    del laser_evm.open_states[:]

    new_account = laser_evm.world_state.create_account(0,
                                                       concrete_storage=True,
                                                       dynamic_loader=None)
    if contract_name:
        new_account.contract_name = contract_name

    for open_world_state in open_states:
        next_transaction_id = get_next_transaction_id()
        transaction = ContractCreationTransaction(
            open_world_state,
            BitVec("creator{}".format(next_transaction_id), 256),
            next_transaction_id,
            new_account,
            Disassembly(contract_initialization_code),
            [],
            BitVec("gas_price{}".format(next_transaction_id), 256),
            BitVec("call_value{}".format(next_transaction_id), 256),
            BitVec("origin{}".format(next_transaction_id), 256),
            CalldataType.SYMBOLIC,
        )
        _setup_global_state_for_execution(laser_evm, transaction)
    laser_evm.exec(True)

    return new_account
Пример #13
0
def execute_contract_creation(laser_evm, contract_initialization_code, contract_name=None):
    """ Executes a contract creation transaction from all open states"""
    open_states = laser_evm.open_states[:]
    del laser_evm.open_states[:]

    new_account = laser_evm.world_state.create_account(0, concrete_storage=True, dynamic_loader=None)
    if contract_name:
        new_account.contract_name = contract_name

    for open_world_state in open_states:
        transaction = ContractCreationTransaction(
            open_world_state,
            BitVec("caller", 256),
            new_account,
            Disassembly(contract_initialization_code),
            [],
            BitVec("gas_price", 256),
            BitVec("call_value", 256),
            BitVec("origin", 256),
            CalldataType.SYMBOLIC
        )

        _setup_global_state_for_execution(laser_evm, transaction)
    laser_evm.exec(True)

    return new_account
Пример #14
0
def execute_contract_creation(laser_evm,
                              contract_initialization_code,
                              contract_name=None) -> Account:
    """ Executes a contract creation transaction from all open states"""
    # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here
    open_states = laser_evm.open_states[:]
    del laser_evm.open_states[:]

    new_account = laser_evm.world_state.create_account(0,
                                                       concrete_storage=True,
                                                       dynamic_loader=None)
    if contract_name:
        new_account.contract_name = contract_name

    for open_world_state in open_states:
        next_transaction_id = get_next_transaction_id()
        transaction = ContractCreationTransaction(
            world_state=open_world_state,
            identifier=next_transaction_id,
            gas_price=BitVec("gas_price{}".format(next_transaction_id), 256),
            gas_limit=8000000,  # block gas limit
            origin=BitVec("origin{}".format(next_transaction_id), 256),
            code=Disassembly(contract_initialization_code),
            caller=BitVecVal(CREATOR_ADDRESS, 256),
            callee_account=new_account,
            call_data=[],
            call_data_type=CalldataType.SYMBOLIC,
            call_value=BitVec("call_value{}".format(next_transaction_id), 256),
        )
        _setup_global_state_for_execution(laser_evm, transaction)
    laser_evm.exec(True)

    return new_account
Пример #15
0
    def runTest(self):

        disassembly = Disassembly(self.code)

        self.assertEqual(
            len(disassembly.blocks), 162,
            'Disassembler error: Incorrect number of blocks generated)')
Пример #16
0
    def __init__(
        self,
        address: Union[BitVec, str],
        code=None,
        contract_name="unknown",
        balances: Array = None,
        concrete_storage=False,
        dynamic_loader=None,
    ) -> None:
        """Constructor for account.

        :param address: Address of the account
        :param code: The contract code of the account
        :param contract_name: The name associated with the account
        :param balance: The balance for the account
        :param concrete_storage: Interpret storage as concrete
        """
        self.nonce = 0
        self.code = code or Disassembly("")
        self.address = (address if isinstance(address, BitVec) else
                        symbol_factory.BitVecVal(int(address, 16), 256))

        self.storage = Storage(concrete_storage,
                               address=self.address,
                               dynamic_loader=dynamic_loader)

        # Metadata
        self.contract_name = contract_name

        self.deleted = False

        self._balances = balances
        self.balance = lambda: self._balances[self.address]
Пример #17
0
    def __init__(
        self,
        address: str,
        code=None,
        contract_name="unknown",
        balance=None,
        concrete_storage=False,
        dynamic_loader=None,
    ):
        """
        Constructor for account
        :param address: Address of the account
        :param code: The contract code of the account
        :param contract_name: The name associated with the account
        :param balance: The balance for the account
        :param concrete_storage: Interpret storage as concrete
        """
        self.nonce = 0
        self.code = code or Disassembly("")
        self.balance = balance if balance else BitVec("{}_balance".format(address), 256)
        self.storage = Storage(
            concrete_storage, address=address, dynamic_loader=dynamic_loader
        )

        # Metadata
        self.address = address
        self.contract_name = contract_name

        self.deleted = False
Пример #18
0
def test_delegate_call(sym_mock, concrete_mock, curr_instruction):
    # arrange
    # sym_mock = mocker.patch.object(delegatecall, "_symbolic_call")
    # concrete_mock = mocker.patch.object(delegatecall, "_concrete_call")
    sym_mock.return_value = []
    concrete_mock.return_value = []
    curr_instruction.return_value = {"address": "0x10"}

    active_account = Account("0x10")
    active_account.code = Disassembly("00")

    environment = Environment(active_account, None, None, None, None, None)
    state = GlobalState(None, environment, Node)
    state.mstate.memory = ["placeholder", "calldata_bling_0"]
    state.mstate.stack = [1, 2, 3]
    assert state.get_current_instruction() == {"address": "0x10"}

    node = Node("example")
    node.contract_name = "the contract name"
    node.function_name = "fallback"

    to = Variable("storage_1", VarType.SYMBOLIC)
    call = Call(node, state, None, "DELEGATECALL", to, None)

    statespace = MagicMock()
    statespace.calls = [call]

    # act
    execute(statespace)

    # assert
    assert concrete_mock.call_count == 1
    assert sym_mock.call_count == 1
Пример #19
0
def get_state():
    active_account = Account("0x0", code=Disassembly("60606040"))
    environment = Environment(active_account, None, None, None, None, None)
    state = GlobalState(None, environment, None, MachineState(gas_limit=8000000))
    state.transaction_stack.append(
        (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)
    )
    return state
Пример #20
0
def test_vmtest(
    test_name: str, pre_condition: dict, action: dict, post_condition: dict
) -> None:
    # Arrange

    accounts = {}
    for address, details in pre_condition.items():
        account = Account(address)
        account.code = Disassembly(details["code"][2:])
        account.balance = int(details["balance"], 16)
        account.nonce = int(details["nonce"], 16)

        accounts[address] = account

    laser_evm = LaserEVM(accounts)

    # Act
    laser_evm.time = datetime.now()

    # TODO: move this line below and check for VmExceptions when gas has been implemented
    if post_condition == {}:
        return

    execute_message_call(
        laser_evm,
        callee_address=action["address"],
        caller_address=action["caller"],
        origin_address=action["origin"],
        code=action["code"][2:],
        gas=action["gas"],
        data=binascii.a2b_hex(action["data"][2:]),
        gas_price=int(action["gasPrice"], 16),
        value=int(action["value"], 16),
    )

    # Assert

    assert len(laser_evm.open_states) == 1

    world_state = laser_evm.open_states[0]
    model = get_model(next(iter(laser_evm.nodes.values())).states[0].mstate.constraints)

    for address, details in post_condition.items():
        account = world_state[address]

        assert account.nonce == int(details["nonce"], 16)
        assert account.code.bytecode == details["code"][2:]

        for index, value in details["storage"].items():
            expected = int(value, 16)
            if type(account.storage[int(index, 16)]) != int:
                actual = model.eval(account.storage[int(index, 16)])
                actual = 1 if actual == True else 0 if actual == False else actual
            else:
                actual = account.storage[int(index, 16)]
            assert actual == expected
Пример #21
0
    def __init__(self,
                 code,
                 creation_code="",
                 name="Unknown",
                 enable_online_lookup=True):

        # Workaround: We currently do not support compile-time linking.
        # Dynamic contract addresses of the format __[contract-name]_____________ are replaced with a generic address
        # Apply this for creation_code & code

        creation_code = re.sub(r'(_{2}.{38})', 'aa' * 20, creation_code)
        code = re.sub(r'(_{2}.{38})', 'aa' * 20, code)

        self.creation_code = creation_code
        self.name = name
        self.code = code
        self.disassembly = Disassembly(
            code, enable_online_lookup=enable_online_lookup)
        self.creation_disassembly = Disassembly(
            creation_code, enable_online_lookup=enable_online_lookup)
Пример #22
0
def get_state():
    world_state = WorldState()
    account = world_state.create_account(balance=10, address=101)
    account.code = Disassembly("60606040")
    environment = Environment(account, None, None, None, None, None)
    state = GlobalState(world_state, environment, None,
                        MachineState(gas_limit=8000000))
    state.transaction_stack.append(
        (MessageCallTransaction(world_state=WorldState(),
                                gas_limit=8000000), None))
    return state
Пример #23
0
    def end(self, global_state, return_data=None):

        if not all([isinstance(element, int) for element in return_data]):
            self.return_data = None
            raise TransactionEndSignal(global_state)

        contract_code = bytes.hex(array.array('B', return_data).tostring())

        global_state.environment.active_account.code = Disassembly(contract_code)
        self.return_data = global_state.environment.active_account.address

        raise TransactionEndSignal(global_state)
Пример #24
0
def test_vmtest(test_name: str, pre_condition: dict, action: dict, post_condition: dict) -> None:
    # Arrange

    accounts = {}
    for address, details in pre_condition.items():
        account = Account(address)
        account.code = Disassembly(details['code'][2:])
        account.balance = int(details['balance'], 16)
        account.nonce = int(details['nonce'], 16)

        accounts[address] = account

    laser_evm = LaserEVM(accounts)

    # Act
    laser_evm.time = datetime.now()
    try:
        execute_message_call(
            laser_evm,
            callee_address=action['address'],
            caller_address=action['caller'],
            origin_address=action['origin'],
            code=action['code'][2:],
            gas=action['gas'],
            data=binascii.a2b_hex(action['data'][2:]),
            gas_price=int(action['gasPrice'], 16),
            value=int(action['value'], 16)
        )
    except VmException as e:
        if post_condition == {}:
            return
        else:
            raise e

    # Assert
    if 'Suicide' not in test_name:
        assert len(laser_evm.open_states) == 1
    else:
        assert len(laser_evm.open_states) == 0
        return

    world_state = laser_evm.open_states[0]

    for address, details in post_condition.items():
        account = world_state[address]

        assert account.nonce == int(details['nonce'], 16)
        assert account.code.bytecode == details['code'][2:]

        for index, value in details['storage'].items():
            expected = int(value, 16)
            actual = get_concrete_int(account.storage[int(index, 16)])
            assert actual == expected
Пример #25
0
def check_annotations(contracts, address, eth, dynld, max_depth=12):

    logging.debug("Executing annotations check")

    for contract in contracts:

        contr_to_const = deepcopy(contract)
        contr_to_const.disassembly = Disassembly(contr_to_const.creation_code)
        contr_to_const.code = contr_to_const.creation_code
        dynloader = DynLoader(eth) if dynld else None
        glbstate = get_constr_glbstate(contr_to_const, address)

        sym_constructor = SymExecWrapper(contr_to_const, address, dynloader,
                                         max_depth, glbstate)
        sym_contract = SymExecWrapper(contract,
                                      address,
                                      dynloader,
                                      max_depth=max_depth)

        constructor_trace = get_construction_traces(
            sym_constructor
        )  # Todo the traces here should not contain references to storages anymore
        for t in constructor_trace:
            t.pp_trace()

        traces = get_transaction_traces(sym_contract)
        print("Start")
        a = process_time()
        print("const: " + str(len(constructor_trace)) + " trans: " +
              str(len(traces)))
        trace_chains = []
        for trace in constructor_trace:
            comp_trace_lvls = trace.apply_up_to_trace_levels(traces, 1)
            if not trace_chains:
                trace_chains = comp_trace_lvls
            else:
                for index in range(len(trace_chains)):
                    trace_chains[index].extend(comp_trace_lvls[index])
            print()
        for lvl in trace_chains:
            print("Traces: " + str(len(lvl)))

        #for tt in trace_chains[-1]:
        #    tt.pp_trace()
        #    for trace_lvl in comp_trace_lvls:
        #        print(len(trace_lvl))
        #        print(sum(map(lambda t: len(t.tran_constraints), trace_lvl))/len(trace_lvl))
        #        for t in trace_lvl:
        #            print("constraints: " + str(len(t.tran_constraints)))
        #            t.pp_trace()
        print(process_time() - a)
Пример #26
0
def test_extcodecopy():
    # Arrange
    new_world_state = WorldState()
    new_account = new_world_state.create_account(balance=10, address=101)
    new_account.code = Disassembly("60616240")
    ext_account = new_world_state.create_account(balance=1000, address=121)
    ext_account.code = Disassembly("6040404040")

    new_environment = Environment(new_account, None, None, None, None, None)
    state = GlobalState(
        new_world_state, new_environment, None, MachineState(gas_limit=8000000)
    )
    state.transaction_stack.append(
        (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)
    )

    state.mstate.stack = [3, 0, 0, 121]
    instruction = Instruction("extcodecopy", dynamic_loader=None)

    # Act
    new_state = instruction.evaluate(state)[0]
    # Assert
    assert new_state.mstate.memory[0:3] == [96, 64, 64]
    def end(self, global_state: GlobalState, return_data=None, revert=False):

        if (not all([isinstance(element, int) for element in return_data])
                or len(return_data) == 0):
            self.return_data = None
            raise TransactionEndSignal(global_state)

        contract_code = bytes.hex(array.array("B", return_data).tostring())

        global_state.environment.active_account.code = Disassembly(
            contract_code)
        self.return_data = global_state.environment.active_account.address
        assert global_state.environment.active_account.code.instruction_list != []

        raise TransactionEndSignal(global_state, revert=revert)
Пример #28
0
def test_codecopy_concrete():
    # Arrange
    active_account = Account("0x0", code=Disassembly("60606040"))
    environment = Environment(active_account, None, None, None, None, None)
    og_state = GlobalState(None, environment, None, MachineState(gas=10000000))

    og_state.mstate.stack = [2, 2, 2]
    instruction = Instruction("codecopy", dynamic_loader=None)

    # Act
    new_state = instruction.evaluate(og_state)[0]

    # Assert
    assert new_state.mstate.memory[2] == 96
    assert new_state.mstate.memory[3] == 64
Пример #29
0
def execute_message_call(
    laser_evm,
    callee_address,
    caller_address,
    origin_address,
    code,
    data,
    gas_limit,
    gas_price,
    value,
    track_gas=False,
) -> Union[None, List[GlobalState]]:
    """Execute a message call transaction from all open states.

    :param laser_evm:
    :param callee_address:
    :param caller_address:
    :param origin_address:
    :param code:
    :param data:
    :param gas_limit:
    :param gas_price:
    :param value:
    :param track_gas:
    :return:
    """
    # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here
    open_states = laser_evm.open_states[:]
    del laser_evm.open_states[:]

    for open_world_state in open_states:
        next_transaction_id = get_next_transaction_id()
        transaction = MessageCallTransaction(
            world_state=open_world_state,
            identifier=next_transaction_id,
            gas_price=gas_price,
            gas_limit=gas_limit,
            origin=origin_address,
            code=Disassembly(code),
            caller=caller_address,
            callee_account=open_world_state[callee_address],
            call_data=ConcreteCalldata(next_transaction_id, data),
            call_value=value,
        )

        _setup_global_state_for_execution(laser_evm, transaction)

    return laser_evm.exec(track_gas=track_gas)
Пример #30
0
    def get_xrefs(self):

        instruction_list = Disassembly(self.code).instruction_list

        xrefs = []

        for instruction in instruction_list:
            if instruction['opcode'] == "PUSH20":
                if instruction['argument']:
                    addr = instruction['argument']

                    if (re.match(r'^0x[a-zA-Z0-9]{40}$', addr) and addr != "0xffffffffffffffffffffffffffffffffffffffff"):
                        if addr not in xrefs:
                            xrefs.append(addr)

        return xrefs