Error: The JSON parameter could not be used because there was no schema for it,

I’ve added schema-embed but still can’t pass parameter on init func, following is my code

// pub type VotingOption = String;
/// The voting options are stored in a vector. The vector index is used to refer
/// to a specific voting option.
/// Number of holder.
pub type TotalHolders = u32;
/// single holder amount
pub type TotalHolderAmount = u64;

/// The parameter type for the contract function `init`.
/// Takes a description, the voting options, and the `end_time` to start the
/// election.
#[derive(Serialize, SchemaType)]
pub struct InitParameter {
    pub end_time: Timestamp,

/// The contract state
#[derive(Serialize, Clone)]
struct State {
    /// The map connects a voter to the index of the voted-for voting option.
    pub holders: BTreeMap<AccountAddress, Amount>,
    /// The last timestamp that an account can vote.
    /// The election is open from the point in time that this smart contract is
    /// initialized until the `end_time`.
    end_time: Timestamp,
    total_holders: TotalHolders,

#[derive(Serialize, SchemaType)]
pub struct VestingView {
    /// The last timestamp that an account can vote.
    /// The election is open from the point in time that this smart contract is
    /// initialized until the `end_time`.
    pub end_time: Timestamp,
    /// The map connects the index of a voting option to the number of votes
    /// it received so far.
    pub holders: BTreeMap<AccountAddress, Amount>,
    pub total_holders: TotalHolders,
    pub current_balance: Amount


/// The different errors that the `vote` function can produce.
#[derive(Reject, Serialize, PartialEq, Eq, Debug, SchemaType)]
pub enum VotingError {
    /// Raised when parsing the parameter failed.
    /// Raised when the vote is placed after the election has ended.
    /// Raised when voting for a voting option that does not exist.
    /// Raised when a smart contract tries to participate in the election. Only
    /// accounts are allowed to vote.

pub type VestingResult<T> = Result<T, VotingError>;

// Contract functions

/// Initialize the contract instance and start the vesting.
/// end_time
#[init(contract = "vesting", parameter = "InitParameter")]
fn init<S: HasStateApi>(
    ctx: &impl HasInitContext,
    _state_builder: &mut StateBuilder<S>,
) -> InitResult<State> {
    // Parse the parameter.
    let param: InitParameter = ctx.parameter_cursor().get()?;

    // Set the state.
    Ok(State {
        holders: BTreeMap::new(),
        end_time: param.end_time,
        total_holders: 0,

/// Enables accounts to vote for a specific voting option. Each account can
/// change its selected voting option with this function as often as it desires
/// until the `end_time` is reached.
/// It rejects if:
/// - It fails to parse the parameter.
/// - A contract tries to vote.
/// - It is past the `end_time`.
    contract = "vesting",
    name = "vest",
    error = "VotingError"
fn vest<S: HasStateApi>(
    ctx: &impl HasReceiveContext,
    host: &mut impl HasHost<State, StateApiType = S>,
    _amount: Amount,
) -> VestingResult<()> {
    // Check that the election hasn't finished yet.
    if ctx.metadata().slot_time() > host.state().end_time {
        return Err(VotingError::VestingFinished);
    // Ensure that the sender is an account.
    let acc = match ctx.sender() {
        Address::Account(acc) => acc,
        Address::Contract(_) => return Err(VotingError::ContractVoter),

    host.state_mut().total_holders += 1;
    // Insert or replace the vote for the account.
        .and_modify(|current_balance| *current_balance += _amount)


#[receive(contract = "vesting", name = "view")]
fn vesting_info<S: HasStateApi>(
    _ctx: &impl HasReceiveContext,
    host: &impl HasHost<State, StateApiType = S>,
) -> ReceiveResult<VestingView> {

    let holders = host.state().holders.clone();
    let total_holders = host.state().total_holders.clone();
    let end_time = host.state().end_time;
    let current_balance = host.self_balance(); // read current balance

    Ok(VestingView {

The code looks correct. Can you explain what exactly you cannot do, and how you are trying to pass the parameters?

Is it using one of the SDKs? Or concordium-client?

@abizjak now the error changed
it says now

unable to serialize parameters: JSON string required

NOTE: no need param here but I also added param in smart contract and still unable to call.
I’m using piggybank dapp frontend to call, following is frontend

function contractUpdatePayload(amount: CcdAmount, contract: Info, method: string) {
    return {
        address: {
            index: contract.index,
            subindex: BigInt(0),
        receiveName: `${}.${method}`,
        maxContractExecutionEnergy: MAX_CONTRACT_EXECUTION_ENERGY,

export async function submitDeposit(connection: WalletConnection, amount: CcdAmount, account: string, contract: Info) {
    // const buff = toBuffer(RAW_SCHEMA, 'base64');
    // const seerial = serializeTypeValue(params, buff);
    // console.log(JSON.stringify(RAW_SCHEMA));
    // const sch = JSON.stringify(RAW_SCHEMA);
    // const param = JSON.stringify(account);
    const param = { User: '3v6SAaexxQ4zwi5AwAncD4yTLtMSXuB9PC7v4dEwu5arMuRRsW' };
    return connection.signAndSendTransaction(
        contractUpdatePayload(amount, contract, 'vest'),

Hi @arslan,

If you provide a schema where a String is expected as input parameter, then you would get the error you mentioned JSON string required.

Try to generate a new schema with cargo concordium build --schema-base64-out - and include that one instead.

Best regards