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 a pallet to demonstrate calling into a contract #228

Closed
wants to merge 31 commits into from

Conversation

ascjones
Copy link
Contributor

An foundational step towards use-ink/ink#1674, developing an API for calling into a contract from the runtime.

This PR

  • adds a new pallet contract-caller which allows calling into a flipper contract
  • uses the existing available API in ink to construct the call for the contract
  • adds the flipper contract with a trait and an e2e test which demonstrates it working: instantiates the contract, invokes the pallet, queries the modified state of the contract.
  • introduces a CI step to run the e2e test.

The next step (in progress) is to work and iterate on the ink API itself, which will involve an ink PR and a PR here to utilize the new API.

@ascjones ascjones requested review from cmichi, athei, SkymanOne and a team as code owners March 15, 2024 17:22
Comment on lines +52 to +81
let ink_account_id =
ink::primitives::AccountId::from(<[u8; 32]>::from(contract.clone()));
let mut flipper: ink::contract_ref!(Flip, ink::env::DefaultEnvironment) =
ink_account_id.into();
let call_builder = flipper.call_mut();

let params = call_builder
.flip()
.ref_time_limit(gas_limit.ref_time())
.proof_size_limit(gas_limit.proof_size())
.params();

// Next step is to explore ways to encapsulate the following into the call builder.
let value = *params.transferred_value();
let data = params.exec_input().encode();
let weight = Weight::from_parts(params.ref_time_limit(), params.proof_size_limit());
let storage_deposit_limit = params.storage_deposit_limit().map(|limit| (*limit).into());

let result = pallet_contracts::Pallet::<T>::bare_call(
who.clone(),
contract.clone(),
value.into(),
weight,
storage_deposit_limit,
data,
pallet_contracts::DebugInfo::Skip,
pallet_contracts::CollectEvents::Skip,
pallet_contracts::Determinism::Enforced,
)
.result?;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the code we want to simplify with a nice API in ink!

pallets/contract-caller/src/lib.rs Outdated Show resolved Hide resolved
pub struct Pallet<T>(_);

#[pallet::config]
pub trait Config: frame_system::Config + pallet_contracts::Config {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just to that here, since contracts inherit from system already

Suggested change
pub trait Config: frame_system::Config + pallet_contracts::Config {
pub trait Config: pallet_contracts::Config {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #[pallet::config] macro requires the explicit implementation of frame_system::Config

@jasl
Copy link

jasl commented Mar 22, 2024

Do you think this PR can resolve my question? https://substrate.stackexchange.com/questions/10685/how-to-call-a-contract-from-pallet-with-specific-interface

I want to extend my pallet through the developers' uploaded contract,
for example,
For an NFT marketplace pallet, I want to allow NFT collection owners to register a few "hooks" (such as on_bought and on_sell) so they can have a restricted way to extend fixed pallet business logic.
So, I want those contracts that serve as a hook, acquired to conform to specific interfaces, and in the pallet, I want to call the typed interface instead of a selector.

@ascjones
Copy link
Contributor Author

Do you think this PR can resolve my question? https://substrate.stackexchange.com/questions/10685/how-to-call-a-contract-from-pallet-with-specific-interface

I want to extend my pallet through the developers' uploaded contract, for example, For an NFT marketplace pallet, I want to allow NFT collection owners to register a few "hooks" (such as on_bought and on_sell) so they can have a restricted way to extend fixed pallet business logic. So, I want those contracts that serve as a hook, acquired to conform to specific interfaces, and in the pallet, I want to call the typed interface instead of a selector.

Yes, you can use the technique I have used in this PR. I am currently working on a nicer API for this, but it is a few weeks away from being ready.

@jasl
Copy link

jasl commented Mar 22, 2024

Do you think this PR can resolve my question? https://substrate.stackexchange.com/questions/10685/how-to-call-a-contract-from-pallet-with-specific-interface
I want to extend my pallet through the developers' uploaded contract, for example, For an NFT marketplace pallet, I want to allow NFT collection owners to register a few "hooks" (such as on_bought and on_sell) so they can have a restricted way to extend fixed pallet business logic. So, I want those contracts that serve as a hook, acquired to conform to specific interfaces, and in the pallet, I want to call the typed interface instead of a selector.

Yes, you can use the technique I have used in this PR. I am currently working on a nicer API for this, but it is a few weeks away from being ready.

That's awesome! Will try when it's landing

@ascjones
Copy link
Contributor Author

ascjones commented Apr 5, 2024

Superseded by use-ink/ink#2189, it is more appropriate to live in that repo since that is where the API will live.

@ascjones ascjones closed this Apr 5, 2024
@Polkadot-Forum
Copy link

This pull request has been mentioned on Polkadot Forum. There might be relevant details there:

https://forum.polkadot.network/t/contracts-on-assethub-roadmap/9513/11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants