Пример #1
0
def process_ast(ast,
                parents=True,
                link_identifiers=True,
                check_return=True,
                alias_analysis=True,
                type_check=True):
    with print_step("Preprocessing AST"):
        if parents:
            set_parents(ast)
        if link_identifiers:
            try:
                link(ast)
            except UnknownIdentifierException as e:
                raise PreprocessAstException(f'\n\nSYMBOL ERROR: {e}')
        try:
            if check_return:
                r(ast)
            if alias_analysis:
                a(ast)
            call_graph_analysis(ast)
            compute_modified_sets(ast)
            check_for_undefined_behavior_due_to_eval_order(ast)
        except AstException as e:
            raise AnalysisException(f'\n\nANALYSIS ERROR: {e}')
    if type_check:
        with print_step("Zkay type checking"):
            try:
                t(ast)
                check_circuit_compliance(ast)
                detect_hybrid_functions(ast)
                check_loops(ast)
            except (TypeMismatchException, TypeException, RequireException,
                    ReclassifyException) as e:
                raise TypeCheckException(f'\n\nCOMPILER ERROR: {e}')
Пример #2
0
 def test_symbol_table(self):
     ast = build_ast(self.example.code())
     set_parents(ast)
     fill_symbol_table(ast)
     link_identifiers(ast)
     contract = ast.contracts[0]
     self.assertEqual(contract.idf.name, self.name)
Пример #3
0
    def test_all_nodes_have_parent(self):
        ast = build_ast(self.example.code())
        set_parents(ast)

        # test
        v = ParentChecker()
        v.visit(ast)
Пример #4
0
    def test_root_children_have_parent(self):
        ast = build_ast(self.example.code())
        set_parents(ast)

        # test
        for c in ast.children():
            self.assertEqual(c.parent, ast)
Пример #5
0
    def test_contract_identifier(self):
        ast = build_ast(self.example.code())
        set_parents(ast)

        # test
        contract = ast.contracts[0]
        idf = contract.idf
        self.assertEqual(idf.parent, contract)
Пример #6
0
    def test_link_identifiers(self):
        ast = build_ast(simple.code())
        set_parents(ast)
        link_identifiers(ast)

        self.get_ast_elements(ast)

        self.assertEqual(self.identifier_expr.target, self.decl)
        self.assertEqual(self.identifier_expr.get_annotated_type(),
                         self.decl.annotated_type)
Пример #7
0
    def test_link_identifiers(self):
        ast = build_ast(simple_storage.code())
        set_parents(ast)
        link_identifiers(ast)
        assignment = ast['SimpleStorage']['set'].body[0]
        self.assertIsInstance(assignment, AssignmentStatement)

        stored_data = assignment.lhs.target
        self.assertEqual(stored_data, ast['SimpleStorage']['storedData'])

        x = assignment.rhs.target
        self.assertEqual(x.idf.name, 'x')
Пример #8
0
def transform_ast(ast: SourceUnit) -> Tuple[SourceUnit, Dict[ConstructorOrFunctionDefinition, CircuitHelper]]:
    """
    Convert zkay to solidity AST + proof circuits

    :param ast: zkay AST
    :return: solidity AST and dictionary which maps all function definitions which require verification
             to the corresponding circuit helper instance.
    """
    zt = ZkayTransformer()
    new_ast = zt.visit(ast)

    # restore all parent pointers and identifier targets
    set_parents(new_ast)
    link_identifiers(new_ast)
    return new_ast, zt.circuits
Пример #9
0
def deep_copy(ast: T, with_types=False, with_analysis=False) -> T:
    """

    :param ast:
    :param with_types: (optional)
    :return: a deep copy of `ast`

    Only parents and identifiers are updated in the returned ast (e.g., inferred types are not preserved)
    """
    assert isinstance(ast, AST)
    v = DeepCopyVisitor(with_types, with_analysis)
    ast_copy = v.visit(ast)
    ast_copy.parent = ast.parent
    set_parents(ast_copy)
    link_identifiers(ast_copy)
    return ast_copy
Пример #10
0
    def test_alias_analysis(self):
        # perform analysis
        ast = build_ast(analysis.code())
        set_parents(ast)
        link_identifiers(ast)
        alias_analysis(ast)

        # generate string, including analysis results
        v = AnalysisCodeVisitor()
        s = v.visit(ast)
        # next statement can be enabled to determine the computed output
        # print(s)

        # check output
        self.maxDiff = None
        self.assertMultiLineEqual(analysis.code(),
                                  re.sub(" +\n", "\n", s.code()))
Пример #11
0
def _replace_ast(old_ast: AST, new_ast: AST):
    new_ast.parent = old_ast.parent
    DeepCopyVisitor.copy_ast_fields(old_ast, new_ast)
    if old_ast.parent is not None:
        set_parents(new_ast)
        link_identifiers(new_ast)
Пример #12
0
class GlobalDefs:
    # gasleft: FunctionDefinition = FunctionDefinition(
    #     idf=Identifier('gasleft'),
    #     parameters=[],
    #     modifiers=[],
    #     return_parameters=[Parameter([], annotated_type=AnnotatedTypeName.uint_all(), idf=Identifier(''))],
    #     body=Block([])
    # )
    # gasleft.idf.parent = gasleft

    address_struct: StructDefinition = StructDefinition(
        Identifier('<address>'), [
            VariableDeclaration([], AnnotatedTypeName.uint_all(),
                                Identifier('balance'))
        ])
    set_parents(address_struct)

    address_payable_struct: StructDefinition = StructDefinition(
        Identifier('<address_payable>'), [
            VariableDeclaration([], AnnotatedTypeName.uint_all(),
                                Identifier('balance')),
            ConstructorOrFunctionDefinition(
                Identifier('send'),
                [Parameter([], AnnotatedTypeName.uint_all(), Identifier(''))],
                ['public'],
                [Parameter([], AnnotatedTypeName.bool_all(), Identifier(''))],
                Block([])),
            ConstructorOrFunctionDefinition(
                Identifier('transfer'),
                [Parameter([], AnnotatedTypeName.uint_all(), Identifier(''))],
                ['public'], [], Block([])),
        ])
    address_payable_struct.members[1].can_be_private = False
    address_payable_struct.members[2].can_be_private = False
    set_parents(address_payable_struct)

    msg_struct: StructDefinition = StructDefinition(Identifier('<msg>'), [
        VariableDeclaration([],
                            AnnotatedTypeName(TypeName.address_payable_type()),
                            Identifier('sender')),
        VariableDeclaration([], AnnotatedTypeName.uint_all(),
                            Identifier('value')),
    ])
    set_parents(msg_struct)

    block_struct: StructDefinition = StructDefinition(Identifier('<block>'), [
        VariableDeclaration([],
                            AnnotatedTypeName(TypeName.address_payable_type()),
                            Identifier('coinbase')),
        VariableDeclaration([], AnnotatedTypeName.uint_all(),
                            Identifier('difficulty')),
        VariableDeclaration([], AnnotatedTypeName.uint_all(),
                            Identifier('gaslimit')),
        VariableDeclaration([], AnnotatedTypeName.uint_all(),
                            Identifier('number')),
        VariableDeclaration([], AnnotatedTypeName.uint_all(),
                            Identifier('timestamp')),
    ])
    set_parents(block_struct)

    tx_struct: StructDefinition = StructDefinition(Identifier('<tx>'), [
        VariableDeclaration([], AnnotatedTypeName.uint_all(),
                            Identifier('gasprice')),
        VariableDeclaration([],
                            AnnotatedTypeName(TypeName.address_payable_type()),
                            Identifier('origin')),
    ])
    set_parents(tx_struct)
Пример #13
0
 def test_alias_analysis(self):
     # perform analysis
     ast = build_ast(self.example.code())
     set_parents(ast)
     link_identifiers(ast)
     alias_analysis(ast)