Now that we're done with the easy stuff, let's dive into complex arbitrary code. From top to bottom, we'll start with the Contract
object.
Consider the following example from the article about Contracts
:
from glider import *
def query():
contracts = (
Contracts()
.mains()
.with_compiler_range("0.8.0", "0.8.26")
.with_struct_name("Config")
.exec(1, 1)
)
result = []
for contract in contracts:
# arbitrary logic
print(contract.source_code())
result.append(contract)
return result
We can't do much with the declarative query anymore without descending to Functions
or Instructions
, but there are still many methods for the logic in the loop. About 20, to be precise, check the documentation.
The most useful are:
.source_code()
, which you've already seen.name
, a property, returns the name of a contract.address()
, returns the address of a contract.enums/errors/events/structs()
, they are similar, return a list of the corresponding objects.functions()
, to get theFunctions
of a contract.state_variables()
, to get theStateVariables
object, which contains the storage variables of a contract.modifiers()
, same as the two above, butModifiers
(what did you expect).parent_contracts()
.base_contracts()
.derived_contracts()
The last three are to work with the inheritance.
Let's stop now because this is one of the most interesting parts of the Contract
object.
.parent_contracts()
returns the inherited contracts without recursion.
For example, look at the glide below:
from glider import *
def query():
contracts = (
Contracts()
.mains()
.exec(1, 1)
)
result = []
for contract in contracts:
print(contract.name)
print(contract.source_code())
result = contract.parent_contracts().exec()
return result
It will return ERC20Permit
and Ownable
for the following contract:
contract TestCoin is ERC20Permit, Ownable {
...
}
-
.base_contracts()
is the same as.parent_contracts()
, but with recursion enabled. This means it'll returnContext
,EIP712
,ERC20
,IERC20
, andIERC20Metadata
in addition to theERC20Permit
andOwnable
for the same contract above. -
The last one,
.derived_contracts()
, works in the opposite direction. It'll return contracts that use, for example,IERC20
as a base:
from glider import *
def query():
contracts = (
Contracts()
.interface_contracts()
.with_name("IERC20")
.exec(1)
)
result = []
for contract in contracts:
print(contract.name)
print(contract.source_code())
result = contract.derived_contracts().exec()
return result # ERC20, ERC20Permit, IERC20Metadata, TestCoin
Don't forget to add
.exec()
after these methods because they returnContracts
too. It's the same as with the declarative query in the beggining of glides, you can change the limit and the offset or add more filtration or descend to functions/instructions.