Skip to content

Constructor Support #89

@aolieman

Description

@aolieman

How can I use komet on a contract that has a __constructor fn?

I'm eager to use komet on my contract, which has a couple of properties that I could verify. Before I'm able to do that, I need to initialize the contract properly. Right now, the hurdle I can't seem to get past is that the contract has a constructor, and any test will fail if the constructor isn't first called by the host.

The constructor just takes three addresses as arguments:

#[contractimpl]
impl SinkContract {
    pub fn __constructor(env: Env, admin: Address, carbon_id: Address, carbonsink_id: Address) {
        env.storage().instance().set(&DataKey::Admin, &admin);
        env.storage().instance().set(&DataKey::CarbonID, &carbon_id);
        env.storage().instance().set(&DataKey::CarbonSinkID, &carbonsink_id);
        env.storage().instance().set(&DataKey::IsActive, &true);
        env.storage().instance().set(&DataKey::SinkMinimum, &1_000_000_i64);  // 100 kg
    }
    ...
}

I can't use testutils to initialize the contract as I normally do in my test suite. The only alternative I'm aware of, is to use the env.deployer() method.

#[contractimpl]
impl TestAdderContract {
    pub fn init(env: Env, wasm_hash: Bytes) {
        let sink_bytes = b"sink_ctr________________________";
        let sink_addr = komet::create_contract(&env, &Bytes::from_array(&env, sink_bytes), &wasm_hash);
        env.storage().instance().set(&DataKey::SinkID, &sink_addr);

        let admin_bytes = b"GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF";
        let admin_addr = komet::address_from_bytes(&env, admin_bytes, false);
        env.storage().instance().set(&DataKey::Admin, &admin_addr);
        let carbon_bytes = b"CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN";
        let carbon_addr = komet::address_from_bytes(&env, carbon_bytes, true);
        env.storage().instance().set(&DataKey::CarbonID, &carbon_addr);
        let csink_bytes = b"CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG";
        let csink_addr = komet::address_from_bytes(&env, csink_bytes, true);
        env.storage().instance().set(&DataKey::CarbonSinkID, &csink_addr);

        let salt = BytesN::from_array(&env, &[0; 32]);
        let constructor_args: Vec<Val> = (admin_addr, carbon_addr, csink_addr).into_val(&env);
        let deployed_address = env
            .deployer()
            .with_address(env.current_contract_address(), salt)
            .deploy_v2(
                BytesN::<32>::from_array(&env, &wasm_hash.try_into().expect("wasm_hash must be 32 bytes")), 
                constructor_args
            );
    }
    ...
}

That crashes kasmer, unfortunately:

  File "/nix/store/wx8w33vpms3jjx7dxc6l6f1afs6y2iz0-python3.10-komet-0.1.71/lib/python3.10/site-packages/komet/kasmer.py", line 217, in deploy_test
    assert proc_res.returncode == 0
AssertionError

For more context, including the contract I want to test and my usual test setup, please see this branch:
https://github.com/stellarcarbon/sorocarbon/tree/komet

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions