Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add import functionality for contracts #1156

Closed
1 task done
Tracked by #1378
kevaundray opened this issue Apr 17, 2023 · 1 comment
Closed
1 task done
Tracked by #1378

Add import functionality for contracts #1156

kevaundray opened this issue Apr 17, 2023 · 1 comment
Assignees
Labels
aztec.nr Helpful for development of Aztec.nr the smart contract framework enhancement New feature or request

Comments

@kevaundray
Copy link
Contributor

kevaundray commented Apr 17, 2023

Problem

Importing other blocks of code is a common feature used in many languages.

From #include in C to import in javascript.

Currently, we have the ability to import Noir programs, but we have not implemented the necessary semantics around importing Noir contracts.

Why is import syntax different for Noir contracts?

Importing Noir contracts are wholly different to importing programs because when you import a function in another library as Noir program, it always gets inlined in your current Noir program.

Take the following two noir libraries:

// lib1
fn foo(x : Field) -> Field {
  x
}
// lib2
use lib1::foo;
fn bar(x : Field) -> Field {
  foo(x)
}

This is equivalent to:

// lib2
fn foo(x : Field) -> Field {
  x
}
fn bar(x : Field) -> Field {
  foo(x)
}

This does not apply for Noir smart contracts and in-fact calling a function from another smart contract is never inlined. This difference is due to the fact that a smart contract has shared state that can only be modified by its own functions, and inlining those functions in another smart contract breaks this property.

Proposed solution

// my_contracts.nr
contract Foo {
   external fn triple_add(a : Field, b : Field, c : Field) -> Field {
      add(a,b) + c
   }
   
   fn add(a : Field, b : Field) -> Field {
      a + b
   }
}
// main.nr
use my_contracts::Foo;
      
contract Bar { 
   fn baz(address_of_foo_contract: Field) {
      let foo_contract_instance: Foo = Foo(address_of_foo_contract);
      let _d: Field = foo_contract_instance. triple_add(a, b, c);
   }
}

The Foo contract above will inline add into triple_add since both functions are secret.

-use my_contracts::Foo;

The Bar contract uses the line to import the Foo contract.

  • let foo_contract_instance: Foo = Foo(address_of_foo_contract);

This line will instantiate a new Foo contract with the given address. All contracts must be instantiated with an address. This is different to the constructor of the contract.

To clarify, lets break down Foo(address_of_foo_contract); further. This can be desugared into:

let some_contract_instance = Contract(address_of_foo_contract);
let foo_contract_instance = some_contract_instance as Foo;

The first line emphasizes the fact that we are doing something closer to dynamic linking; at runtime the address_of_foo_contract is used to create a Contract instance. This could be any contract, it all depends on what address_of_foo_contract is. Since our contract will not work if it is not a Foo contract, we then assume that the methods in Foo are available on this Contract instance by using the as keyword.

The above two lines is not posible in Noir and I just used it to emphasize further what is happening.

  • let _d: Field = foo_contract_instance. triple_add(a, b, c);

Remember, this is a function call which is not inlined.

Alternatives considered

No response

Additional context

A nice to have is a way for a contract to say "I don't care what the contract instance is, it just needs to adhere to these methods" -- This requires something like traits/interface, so we avoid it for now.

We would also need to figure out how to error when a contract instantiated at runtime, does not provide a method it should.

Submission Checklist

  • Once I hit submit, I will assign this issue to the Project Board with the appropriate tags.
@kevaundray kevaundray added this to Noir Apr 17, 2023
@github-project-automation github-project-automation bot moved this to 📋 Backlog in Noir Apr 17, 2023
@kevaundray
Copy link
Contributor Author

The part on function types has been moved to this issue: #1168

@kevaundray kevaundray self-assigned this Jul 25, 2023
@Savio-Sou Savio-Sou added aztec.nr Helpful for development of Aztec.nr the smart contract framework and removed private-smart-contracts labels Apr 10, 2024
@github-project-automation github-project-automation bot moved this from 📋 Backlog to ✅ Done in Noir Apr 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aztec.nr Helpful for development of Aztec.nr the smart contract framework enhancement New feature or request
Projects
Archived in project
Development

No branches or pull requests

3 participants