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

ink contract error #1891

Open
amiyatulu opened this issue Dec 31, 2024 · 3 comments
Open

ink contract error #1891

amiyatulu opened this issue Dec 31, 2024 · 3 comments

Comments

@amiyatulu
Copy link

amiyatulu commented Dec 31, 2024

Command using cargo contract:
cargo contract call --contract 5FaXMndJSH2CvFn8twGyzZZc57qJHBiUMhSnE5d1pYCJYiTS --message flip --execute --suri //Alice
It works successfully.

Subxt code:

#![allow(missing_docs)]
use subxt::{OnlineClient, PolkadotConfig};
use subxt_signer::sr25519::dev;
use blake2::{Blake2s256, Digest};
use subxt::utils::AccountId32;
use std::str::FromStr;
use polkadot::runtime_types::sp_weights::weight_v2::Weight;

// Generate an interface that we can use from the node's metadata.
#[subxt::subxt(runtime_metadata_path = "metadata.scale")]
pub mod polkadot {}


const PROOF_SIZE: u64 = u64::MAX / 2;

fn blake2_256(input: &[u8]) -> Vec<u8> {
    let mut hasher = Blake2s256::new();
    hasher.update(input);
    hasher.finalize().to_vec()
}


#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a new API client, configured to talk to Polkadot nodes.
    let api = OnlineClient::<PolkadotConfig>::from_url("ws://127.0.0.1:9944")
        .await?;

        let contract = "5FaXMndJSH2CvFn8twGyzZZc57qJHBiUMhSnE5d1pYCJYiTS";

        let mut call_data = Vec::<u8>::new();
        call_data.append(&mut (&blake2_256("flip".as_bytes())[0..4]).to_vec());

        let payload = polkadot::tx().contracts().call(
            AccountId32::from_str(contract).unwrap().into(),
            0,
            Weight {
                ref_time: 242961830,
                proof_size: PROOF_SIZE,
            },
            None,
            call_data,
        );

    let from = dev::alice();
    let events = api
        .tx()
        .sign_and_submit_then_watch_default(&payload, &from)
        .await?
        .wait_for_finalized_success()
        .await?;


    Ok(())
}

It gives error, Error: Runtime(Module(ModuleError(<Contracts::ContractReverted>)))

@amiyatulu
Copy link
Author

The following code works:

#![allow(missing_docs)]
use subxt::{OnlineClient, PolkadotConfig};
use subxt_signer::sr25519::dev;
use blake2::{Blake2s256, Digest};
use subxt::utils::AccountId32;
use std::str::FromStr;
use polkadot::runtime_types::sp_weights::weight_v2::Weight;
use subxt::tx::TxStatus;
use ink_metadata::InkProject;
use parity_scale_codec::{Encode, Decode};
use std::fs;
use anyhow::{Result, anyhow};
// Generate an interface that we can use from the node's metadata.
#[subxt::subxt(runtime_metadata_path = "./artifacts/metadata.scale",)]
pub mod polkadot {}

const PROOF_SIZE: u64 = u64::MAX / 2;


fn generate_call_data(metadata_path: &str, method_name: &str, args: &[impl Encode]) -> Result<Vec<u8>> {
    // Read the metadata file
    let metadata_content = fs::read_to_string(metadata_path)?;
    let metadata: InkProject = serde_json::from_str(&metadata_content)?;

    // Find the specified method in the metadata
    let message = metadata
        .spec()
        .messages()
        .iter()
        .find(|msg| msg.label() == method_name)
        .ok_or_else(|| anyhow!("Method `{}` not found in metadata", method_name))?;

    // Encode the selector
    let mut call_data = message.selector().to_bytes().to_vec();
    // Encode the arguments and append them to the selector
    for arg in args {
        call_data.extend(arg.encode());
    }

    Ok(call_data)
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a new API client, configured to talk to Polkadot nodes.
    let api = OnlineClient::<PolkadotConfig>::from_url("ws://127.0.0.1:9944")
        .await?;

    let contract = "5CZWhGiwKzocfeP5G9Ta8ZprpcardvisMcEWxoyANB9ziWq6";

 
    let metadata_path = "./artifacts/flipper.json"; // Replace with the actual path
    let method_name = "flip"; // The method to call
    let args: Vec<bool> = vec![]; // For example, `flip` takes no arguments

    // Generate the call data
    let call_data = generate_call_data(metadata_path, method_name, &args)?;

    println!("Encoded call data: 0x{}", hex::encode(call_data.clone()));

    let payload = polkadot::tx().contracts().call(
        subxt::utils::MultiAddress::Id(AccountId32::from_str(contract).unwrap()),
        0,
        Weight {
            ref_time: 242961830,
            proof_size: PROOF_SIZE,
        },
        None,
        call_data.clone(),
    );

    // Submit the balance transfer extrinsic from Alice, and wait for it to be successful
    // and in a finalized block. We get back the extrinsic events if all is well.
    let from = dev::alice();
    let events = api
    .tx()
    .sign_and_submit_then_watch_default(&payload, &from)
    .await?
    .wait_for_finalized_success()
    .await?;
    Ok(())
}

toml file

[dependencies]
anyhow = "1.0.95"
blake2 = "0.10.6"
cargo-contract = "5.0.2"
hex = "0.4.3"
ink_metadata = "5.1.1"
parity-scale-codec = "3.6.12"
scale-decode = "0.16.0"
serde_json = "1.0.134"
subxt = "0.38.0"
subxt-signer = "0.38.0"
tokio =  { version = "1.42.0", features = ["rt", "rt-multi-thread", "macros"] }

@amiyatulu
Copy link
Author

Can you provide example for get calls?

@niklasad1
Copy link
Member

niklasad1 commented Jan 2, 2025

Hey hey,

From my understanding subxt works as intended but perhaps something is wrong i.e. how you call contract such as weight or something but I have no idea. Fails here: https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/contracts/src/lib.rs#L959

Subxt has no guides etc how to call smart contracts, the best would be to ask in the ink! repo instead.

Perhaps if you want to debug it yourself you could enable RUST_LOG=runtime::contracts=debug on the contracts node yourself.

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

No branches or pull requests

2 participants