Glider gitbook
GliderRVSS Calculator Ask the Community
  • Glider introduction
  • 🏄Writing Queries
  • ✍️Glider and Declarative Query Writing
  • 🎓Glider: The Basics
    • Intro to Python
      • Basic Python
      • Advanced Python
    • Intro to Glider
    • Instructions
      • Learning Instructions
      • Exercises
    • Functions
      • Learning Functions
      • Exercises
    • Contracts
      • Learning Contracts
      • Exercises
    • Bonus Challenges
  • 📙API
    • 📌Main concepts
    • Iterables
      • APISet
      • APIList
    • Argument
      • Argument.backward_df()
      • Argument.data
      • Argument.df_reaches_from_functions_arguments()
      • Argument.df_reaching_functions_arguments()
      • Argument.forward_df()
      • Argument.get_parent()
      • Argument.index
      • Argument.memory_type
      • Argument.name
      • Argument.procedure_graph_node
      • Argument.source_code()
      • Argument.type
    • Arguments
      • Arguments.list()
      • Arguments.with_memory_type()
      • Arguments.with_name()
      • Arguments.with_type()
      • Arguments.with_type_convertible()
      • Convertor
        • Convertor.add()
        • Convertor.can_convert()
        • Convertor.set_conversions()
    • Contract
      • Contract.address()
      • Contract.base_contracts()
      • Contract.chain_id()
      • Contract.constructor()
      • Contract.derived_contracts()
      • Contract.enums()
      • Contract.errors()
      • Contract.events()
      • Contract.functions()
      • Contract.is_lib()
      • Contract.is_main()
      • Contract.modifiers()
      • Contract.name
      • Contract.parent_contracts()
      • Contract.pragmas()
      • Contract.source_code()
      • Contract.state_variables()
      • Contract.structs()
    • Contracts
      • Contracts.exec()
      • Contracts.functions()
      • Contracts.interface_contracts()
      • Contracts.mains()
      • Contracts.with_name_prefix()
      • Contracts.with_name_regex()
      • Contracts.with_name_suffix()
      • Contracts.non_interface_contracts()
      • Contracts.with_all_function_names()
      • Contracts.with_compiler_range()
      • Contracts.with_compiler_range_not()
      • Contracts.with_error_name()
      • Contracts.with_error_prefix()
      • Contracts.with_error_regex()
      • Contracts.with_error_signature()
      • Contracts.with_error_suffix()
      • Contracts.with_event_name()
      • Contracts.with_event_prefix()
      • Contracts.with_event_regex()
      • Contracts.with_event_signature()
      • Contracts.with_event_suffix()
      • Contracts.with_function_name()
      • Contracts.with_function_name_not()
      • Contracts.with_one_of_the_function_names()
      • Contracts.with_name()
      • Contracts.with_name_not()
      • Contracts.with_struct_field_name()
      • Contracts.with_struct_field_type()
      • Contracts.with_struct_fields_count()
      • Contracts.with_struct_name()
    • Enum
      • Enum.data
      • Enum.max
      • Enum.min
      • Enum.name
      • Enum.values
    • Enums
      • Enums.exec()
    • Error
      • Error.args
      • Error.name
      • Error.signature
    • Errors
      • Errors.exec()
    • Event
      • Event.arg_list()
      • Event.name
      • Event.signature
    • Function
      • Function.caller_functions()
      • Function.extended_caller_functions()
      • Function.has_modifiers()
      • Function.is_constructor()
      • Function.is_external()
      • Function.is_global()
      • Function.is_internal()
      • Function.is_payable()
      • Function.is_private()
      • Function.is_public()
      • Function.is_pure()
      • Function.is_view()
      • Function.modifiers()
      • Function.properties()
      • Function.return_instructions()
      • Function.return_tuple()
    • Functions
      • Functions.constructors()
      • Functions.exec()
      • Functions.extended_caller_functions()
      • Functions.extended_caller_modifiers()
      • Functions.with_all_properties()
      • Functions.with_declarer_contract_name()
      • Functions.with_modifier_name()
      • Functions.without_modifier_name()
      • Functions.with_modifier_name_regex()
      • Functions.with_modifier_signature()
      • Functions.with_one_of_the_modifier_names()
      • Functions.without_modifier_names()
      • Functions.with_one_of_the_modifier_name_regexes()
      • Functions.with_one_property()
      • Functions.without_properties()
      • Functions.with_all_modifier_names()
      • Functions.without_modifiers()
      • Functions.with_declarer_contract_name()
    • Modifier
      • Modifier.functions()
      • Modifier.placer_instructions()
      • Modifier.properties()
    • Modifiers
      • Modifiers.exec()
      • Modifiers.placer_instructions()
    • Callable
      • Callable.address()
      • Callable.arguments()
      • Callable.break_instructions()
      • Callable.callee_functions()
      • Callable.callee_values()
      • Callable.calls_instructions()
      • Callable.catch_instructions()
      • Callable.continue_instructions()
      • Callable.end_asm_instructions()
      • Callable.end_if_instructions()
      • Callable.end_loop_instructions()
      • Callable.entry_point_instructions()
      • Callable.expression_instructions()
      • Callable.extended_callee_functions()
      • Callable.extended_instructions()
      • Callable.get_contract()
      • Callable.get_reachable_instructions()
      • Callable.hashed_signature()
      • Callable.if_instructions()
      • Callable.if_loop_instructions()
      • Callable.instructions()
      • Callable.local_variables()
      • Callable.name
      • Callable.new_contract_instructions()
      • Callable.signature()
      • Callable.source_code()
      • Callable.start_asm_instructions()
      • Callable.start_loop_instructions()
      • Callable.throw_instructions()
      • Callable.try_instructions()
    • Callables
      • Callables.contracts()
      • Callables.extended_callee_functions()
      • Callables.instructions()
      • Callables.with_name_prefix()
      • Callables.with_name_prefixes()
      • Callables.with_name_regex()
      • Callables.with_name_regexes()
      • Callables.with_name_suffix()
      • Callables.with_name_suffixes()
      • Callables.with_arg_count()
      • Callables.with_arg_memory_type()
      • Callables.with_arg_name()
      • Callables.with_arg_type()
      • Callables.with_arg_types()
      • Callables.with_hashed_signature()
      • Callables.with_name()
      • Callables.without_name()
      • Callables.with_one_of_the_names()
      • Callables.without_names()
      • Callables.with_signature()
      • Callables.with_signatures()
      • Callables.with_callee_names()
      • Callables.with_declarer_contract_name()
      • MethodProp
        • MethodProp.EXTERNAL
        • MethodProp.HAS_ARGS
        • MethodProp.HAS_CALLEES
        • MethodProp.HAS_ERRORS
        • MethodProp.HAS_MODIFIERS
        • MethodProp.HAS_STATE_VARIABLES_READ
        • MethodProp.HAS_STATE_VARIABLES_WRITTEN
        • MethodProp.INTERNAL
        • MethodProp.IS_CONSTRUCTOR
        • MethodProp.IS_GLOBAL
        • MethodProp.IS_PAYABLE
        • MethodProp.IS_PURE
        • MethodProp.IS_VIEW
        • MethodProp.PRIVATE
        • MethodProp.PUBLIC
    • Instruction
      • Instruction.backward_df()
      • Instruction.callee_names()
      • Instruction.extended_previous_instructions()
      • Instruction.forward_df()
      • Instruction.get_callees()
      • Instruction.get_component()
      • Instruction.get_components()
      • Instruction.get_dest()
      • Instruction.get_parent()
      • Instruction.get_value()
      • Instruction.is_break()
      • Instruction.is_call()
      • Instruction.is_catch()
      • Instruction.is_cmp()
      • Instruction.is_continue()
      • Instruction.is_end_assembly()
      • Instruction.is_end_if()
      • Instruction.is_end_loop()
      • Instruction.is_entry_point()
      • Instruction.is_expression()
      • Instruction.is_from_assembly()
      • Instruction.is_if()
      • Instruction.is_if_loop()
      • Instruction.is_new_contract()
      • Instruction.is_placer()
      • Instruction.is_return()
      • Instruction.is_start_assembly()
      • Instruction.is_start_loop()
      • Instruction.is_storage_read()
      • Instruction.is_storage_write()
      • Instruction.is_throw()
      • Instruction.is_try()
      • Instruction.next_block()
      • Instruction.next_instruction()
      • Instruction.next_instructions()
      • Instruction.extended_next_instructions()
      • Instruction.previous_instruction()
      • Instruction.previous_instructions()
      • Instruction.extended_previous_instructions()
      • Instruction.solidity_callee_names()
      • Instruction.source_code()
      • BreakInstruction
      • CatchInstruction
        • CatchInstruction.get_block_instructions()
      • ContinueInstruction
      • EndAssemblyInstruction
      • EndIfInstruction
      • EndLoopInstruction
      • EntryPointInstruction
      • ExpressionInstruction
      • IfInstruction
        • IfInstruction.first_false_instruction()
        • IfInstruction.first_true_instruction()
        • IfInstruction.get_condition()
        • Condition
          • Condition.is_eq()
          • Condition.is_geq()
          • Condition.is_gr()
          • Condition.is_le()
          • Condition.is_leq()
      • IfLoopInstruction
      • NewVariableInstruction
      • PlaceholderInstruction
      • ReturnInstruction
      • StartAssemblyInstruction
        • StartAssemblyInstruction.get_block_instructions()
      • StartLoopInstruction
      • ThrowInstruction
      • TryInstruction
        • TryInstruction.get_block_instructions()
      • CatchInstruction
        • CatchInstruction.get_block_instructions()
    • Instructions
      • Instructions.asm_block_instructions()
      • Instructions.break_instructions()
      • Instructions.calls()
      • Instruction.catch_instructions()
      • Instructions.continue_instructions()
      • Instructions.delegate_calls()
      • Instructions.delegate_calls_from_assembly()
      • Instructions.delegate_calls_non_assembly()
      • Instructions.end_asm_instructions()
      • Instructions.end_if_instructions()
      • Instructions.end_loop_instructions()
      • Instructions.entry_point_instructions()
      • Instructions.exec()
      • Instructions.expression_instructions()
      • Instructions.external_calls()
      • Instructions.functions()
      • Instructions.high_level_static_calls()
      • Instructions.if_instructions()
      • Instructions.if_loop_instructions()
      • Instructions.internal_calls()
      • Instructions.library_calls()
      • Instructions.low_level_function_calls()
      • Instructions.low_level_static_calls()
      • Instructions.modifiers()
      • Instructions.new_contract_instructions()
      • Instructions.new_variable_instructions()
      • Instructions.placeholder_instructions()
      • Instructions.return_instructions()
      • Instructions.start_asm_instructions()
      • Instructions.start_loop_instructions()
      • Instructions.throw_instructions()
      • Instructions.try_instructions()
      • Instructions.with_all_callee_function_names()
      • Instructions.with_callee_function_name()
      • Instructions.with_callee_function_name_prefix()
      • Instructions.with_callee_function_name_suffix()
      • Instructions.with_callee_function_signature()
      • Instructions.with_one_of_callee_function_names()
      • Instructions.without_callee_function_name()
      • Instructions.without_callee_function_names()
    • Value
      • Value
        • Value.expression
        • Value.is_main_value()
        • Value.parent_value
        • Value.get_callee_values()
        • Value.get_state_vars()
        • Value.get_local_vars()
        • Value.get_global_vars()
        • Value.get_arg_vars()
        • Value.get_vars()
      • ValueExpression
        • ValueExpression.get_dest()
        • ValueExpression.get_component()
        • ValueExpression.get_components()
      • Var
        • Var.backward_df()
        • Var.forward_df()
        • Var.get_object_of_var()
        • Var.get_parent()
        • Var.procedure_graph_node
        • Var.type
      • Literal
        • Literal.get_type()
        • Literal.get_value()
      • Call
        • Call.signature
        • Call.name
        • Call.get_contract_name()
        • Call.get_args()
        • Call.get_arg()
        • Call.get_call_gas()
        • Call.get_call_qualifier()
        • Call.get_call_salt()
        • Call.get_call_type()
        • Call.get_call_value()
        • Call.get_function()
        • Call.get_special_params()
        • Call.kv_parameters()
        • CallType
          • CallType.EVENT
          • CallType.EXTERNAL
          • CallType.INTERNAL
          • CallType.LIBRARY
          • CallType.LOW_LEVEL
          • CallType.NEW_ARR
          • CallType.NEW_ELEMENTARY_TYPE:
          • CallType.NEW_STRUCT
          • CallType.PRIVATE
          • CallType.PUBLIC
          • CallType.SOLIDITY
          • CallType.TYPE_CONVERSION
    • Point
      • Point
        • Point.backward_df()
        • Point.forward_df()
        • Point.extended_backward_df()
        • Point.extended_forward_df()
        • Point.has_global_df()
        • Point.has_extended_global_df()
        • Point.get_parent()
        • Point.get_all_tainted_paths_affecting_point()
        • Point.get_tainted_path_affecting_point()
        • Point.get_tainted_sources_affecting_point()
        • Point.df_reaching_functions_arguments()
        • Point.df_reaches_from_functions_arguments()
      • ArgumentPoint
        • ArgumentPoint.get_variable()
      • ArgumentPoints
        • ArgumentsPoints.with_memory_type()
        • ArgumentPoints.with_name()
        • ArgumentPoints.with_type()
        • ArgumentPoints.list()
      • ExternalPoint
        • ExternalPoint.get_variable()
        • ExternalPoint.source_code()
      • GlobalPoint
        • GlobalPoint.get_variable()
      • StatePoint
        • StatePoint.get_variable()
      • VarValue
        • VarValue.backward_df()
        • VarValue.extended_backward_df()
        • VarValue.extended_forward_df()
        • VarValue.forward_df()
        • VarValue.get_defining_points()
        • VarValue.get_object_of_var()
        • VarValue.get_parent()
        • VarValue.type
    • Variables
      • Variable
        • Variable.canonical_name
        • Variable.data
        • Variable.name
        • Variable.source_code()
        • Variable.type
      • StateVariables
        • StateVariables
          • StateVariables.exec()
          • StateVariables.with_all_properties()
          • StateVariables.with_one_property()
          • StateVariables.with_type()
          • StateVariable.with_name()
        • StateVariableProp
        • StateVariable
          • StateVariable.contract()
          • StateVariable.is_accessible()
          • StateVariable.is_constant()
          • StateVariable.is_immutable()
          • StateVariable.is_internal()
          • StateVariable.is_private()
          • StateVariable.is_public()
          • StateVariable.properties()
          • StateVariable.source_code()
      • LocalVariables
        • LocalVariables
          • LocalVariables.with_memory_type()
          • LocalVariables.with_type()
        • LocalVariable
          • LocalVariable.get_parent()
          • LocalVariable.property
          • LocalVariable.source_code()
      • GlobalVariables
      • ArgumentVariable
        • ArgumentVariable.index
        • ArgumentVariable.data
        • ArgumentVariable.memory_type
        • ArgumentVariable.source_code()
    • Struct
      • Struct.data
      • Struct.fields
      • Struct.name
    • StructField
      • StructField.name
      • StructField.type
    • Structs
      • Structs.exec()
    • Internal
      • CallGraph
        • CallGraph.all_nodes()
        • CallGraph.get_corresponding_node_for_function()
        • CallGraph.nodes()
        • CallGraph.with_name()
        • CallGraph.with_name_not()
        • CallGraph.with_name_prefix()
        • CallGraph.with_name_suffix()
      • CallNode
        • CallNode.callable()
        • CallNode.callable_name()
        • CallNode.callee_functions()
        • CallNode.callee_modifiers()
        • CallNode.callees()
        • CallNode.caller_functions()
        • CallNode.caller_modifiers()
        • CallNode.callers()
        • CallNode.get_extended_callees()
        • CallNode.get_extended_callers()
        • CallNode.is_function
        • CallNode.is_modifier
      • Queryable
        • Queryable.query_aggregator
      • NoneObject
        • NoneObject.dump_into_json()
        • NoneObject.instructions()
        • NoneObject.name()
  • Changelog
  • 🚧Limitations
  • 🔧Glider Usage
  • 🗺️Roadmap
  • 👥Comparison with other tools
  • ⚖️Legal Notices
    • Privacy Notice
    • Terms and Conditions
Powered by GitBook
On this page
  • What are Instructions
  • Finding Instructions
  • Foundational Instructions Query
  • Query Goal
  • Breaking The Query Down
  • Step 1 - Finding Instructions
  • Step 2 - Execute query
  • Step 3 - Printing function call arguments
  • Step 4 - Returning the Results
  • Query Results
  • Running the Query
  • Interpreting the Results
  1. Glider: The Basics
  2. Instructions

Learning Instructions

PreviousInstructionsNextExercises

Last updated 22 days ago

What are Instructions

Instructions can be thought of as individual lines of code within a function. They can include anything from an if statement or a function call to a return statement.

Instructions are the building blocks of Solidity contracts and represent the operations that the EVM (Ethereum Virtual Machine) will execute. This is why we refer to them as instructions.

Finding Instructions

Let's start by running a simple query to find some instructions:

from glider import *

def query():
    return Instructions().exec(10)

After running this query in the Glider IDE. You should find 10 instructions returned in the Output panel.

Foundational Instructions Query

Now that we understand what instructions are, let's walk through our second foundational query in this series, a Glider query designed to look for Solidity instructions that call Solidity's famous transferFrom function. Before we break down the query, let's identify the query goal.

Query Goal

  1. Find Solidity instructions that call the transferFrom() function - an ERC-20 function used to transfer tokens from one address to another.

  2. Extract and inspect the arguments passed to each transferFrom() call.

The query can be found below:

from glider import *

def query():
    instructions = (
        Instructions()
        .with_callee_name("transferFrom")
        .exec(10)
    )

    instructions.filter(lambda instruction : print(instruction.get_value().get_args().expression))

    return instructions

Breaking The Query Down

Step 1 - Finding Instructions

In the first part of our query, we create an instance of the Instructions class:

Instructions()

By initializing this class, we gain access to a variety of Instruction API methods provided by Glider. These methods allow us to further filter and query instructions programmatically.

Next, we use the .with_callee_name() method, which allows us to locate instructions that contain function calls to transferFrom.

This method requires a single argument - the name of the function we want to search for. In our case, we pass "transferFrom" as a string:

.with_callee_name("transferFrom")

Step 2 - Execute query

Now that we’ve defined a query to search for instructions that call transferFrom, we need to execute it. To do this, we call the .exec() method, which instructs Glider to run the query and return 10 results:

.exec(10)

Understanding exec()

The .exec() method accepts two optional arguments:

  • Limit – Specifies how many results Glider should return.

  • Offset (optional) – Defines where Glider should start the search (useful for pagination).

In our case, we pass in 10 which tells Glider to return the first 10 results. The offset argument is optional so for now we ignore it.

Step 3 - Printing function call arguments

Now that we have our query results, we can extract additional info from our instructions. In this case, we want to analyze the arguments passed into the transferFrom function calls.

Using filter() to iterate through results

The .filter() method accepts either a named function or a lambda function. In our query, we pass a lambda function to filter():

lambda instruction : print(instruction.get_value().get_args().expression)

Breaking Down the Lambda Function

Inside the lambda function, we have the following code:

print(instruction.get_value().get_args().expression)

Let’s break it down by ignoring print() for a moment and focusing on:

instruction.get_value().get_args().expression

This expression retrieves the arguments passed to the transferFrom function from each instruction.

Tip: An expression is a piece of code that returns a value when executed. Expressions can be written in many ways and can return different types of values. In our case, we are specifically interested in expressions that return True or False.

What's exactly happening here?

To extract the arguments passed into the transferFrom function, we call the following methods in sequence:

  • get_value() - Every instruction contains a value, which represents what the instruction is doing. There are different types of values. Since we are analyzing function calls, this method returns a value representing the transferFrom function call. We call a Call value.

  • get_args() - This method is called on the Call value returned by .get_value(). get_args() retrieves the list of arguments passed to the transferFrom function.

  • expression - This final call converts each argument into its source code representation, allowing us to see how the argument appears in Solidity.

expression is not a method, it’s a property. While the distinction between methods and properties goes beyond the scope of this series, it’s important to note that because expression is a property, we do not need to use parentheses () when calling it.

For example, instead of writing:

instruction.get_value().get_args().expression()

We call it by:

instruction.get_value().get_args().expression

This allows us to retrieve the source code representation of the argument directly.

End Result

When we check the final output, we see that the query returns an array representing the arguments passed into each transferFrom function call:

"['_from', 'this', '_value']"

Printing Output in the Glider IDE

Glider IDE provides a useful Debug panel where we can print out query results for inspection. To take advantage of this feature, we use the standard print() function, which allows us to output any number of arguments directly to the Debug panel.

Since our query retrieves a list of function arguments, we can print them as follows:

print(instruction.get_value().get_args().expression)

Step 4 - Returning the Results

In the final step, we return the query results so they can be displayed in the Glider IDE Output panel.

Since the query() function is expected to return a list, we ensure it returns our filtered instructions query results (represented as a list):

return instructions

Query Results

Now that we’ve reviewed the query, let’s run it in the Glider IDE.

Running the Query

Paste the following query into the Glider IDE, click "Run", and wait for the results:

from glider import *

def query():
    instructions = (
        Instructions()
        .with_callee_name("transferFrom")
        .exec(10)
    )
  
    instructions.filter(lambda instruction : print(instruction.get_value().get_args().expression))

    return instructions

Interpreting the Results

Once the query completes, Glider returns a series of instructions, each containing:

  • The instruction source code

  • The contract address for every instruction

  • A printed list of transferFrom arguments from the results

Each instruction represents a call to the transferFrom function, and we can now view, in a structured and programmatic way, every argument that was passed into these function calls.

This demonstrates how Glider can efficiently and elegantly analyze function arguments within Solidity smart contracts.

For a full list of available Instructions methods, refer to the .

exec() returns a special type of list called . For now, we won’t focus on the differences between a Python List and APIList, as they won’t impact our use case in this series.

There are multiple ways to achieve this, but for this query, we use the provided by Glider.

We’ve previously discussed using filter to in an earlier section. Here, we’ll use filter again to iterate through our results.

In our query, the instruction variable represents a single instruction from the instructions list. Using the instruction variable, we can apply a to execute a series of methods in sequence.

🎓
Glider API documentation
APIList
iterate through results
method chain call
.filter() method
Glider IDE instruction output results