2

I'm a developer who wants to call the ink contract's function from the outside. I already know that ink contract supports cross-contract. But what I want to do is call the function using subxt or node_runtime crate or etc. I don't want to use polkadot js, but want to implement all features in rust and test it. (rust version of web3.js and polkadot.js)

I tried to implement this by using this function: https://github.com/paritytech/subxt/blob/master/testing/integration-tests/src/frame/contracts.rs#L136 but I don't know how to use this function in testnet(rococo or Shibuya) or my local node.

And I also tried to use node_runtime and many other things, but I couldn't make it.

Thank you for any support.

1 Answer 1

4

With Rust, it's a bit more complicated than with JS/TS.

Here's an example of how to call a contract using subxt:

// assuming you have `api` and the contract address
let mut call_data = Vec::<u8>::new();
        //append the selector
call_data.append(&mut (&blake2_256("method_name".as_bytes())[0..4]).to_vec());
        //append the arguments
call_data.append(&mut scale::Encode::encode(&(
            AccountId32::from_string(&arg1).ok()?,
            arg2,
            arg3,
        )));
api.tx().contracts().call(
            AccountId32::from_string(contract).ok()?.into(), // contract address
            0, // transferred_value
            20_000_000_000, // gas limit
            None, // storage deposit limit
            call_data, // the call data
        ))
        .sign_and_submit(&signer) // your signer object

8
  • Thank you for answer! But set api is what I don't know. How do you set api for this? let api = OnlineClient::<PolkadotConfig>::new().await?; This doesn't have api.tx().contracts(). Thank you!
    – Lewis
    Aug 8, 2022 at 13:23
  • Yes, you're right, I missed the updated versions. You should instead use polkadot::tx().contracts().call(data). Aug 9, 2022 at 14:03
  • Sorry for the repeated question. But I'm still stuck in there. When I use an updated subxt, ["no method named contracts found for struct polkadot::TransactionApi in the current scope"] Below is my code. let call_tx = polkadot::tx().contracts().call(AccountId32::from_string(contract).into(), 0, 20_000_000_000, None, call_data, ); where pub mod polkadot{} is from artifacts/polakdot_metadata.scale
    – Lewis
    Aug 9, 2022 at 16:12
  • 1
    Yes, I'm running that. Hmm. I think I need to look into it more. Anyway, your answer helped me so much! Thank you:)
    – Lewis
    Aug 11, 2022 at 1:30
  • 1
    Just to add, one thing you can do is go to polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer and point it at the node you'd like to call contract code on. See what extrinsics you can submit via that UI. If you can't see contract calls there, that'll be why you also can't see them via Subxt. Also, make sure that Subxt is pointed at metadata for the node you want to talk to so that it knows about any contract stuff that might be available :)
    – jsdw
    Nov 5, 2022 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.