Skip to main content

Code

The CodePromise class allows the developer to manage calls to the instantiate_with_code dispatchable in the contracts pallet. It is useful in cases where an existing codeHash is not available, meaning that the code has never been deployed to the blockchain in its current form.

The instantiate_with_code dispatchable uploads the wasm code to the blockchain and creates a new instance in one go. Learn how it works under the hood in the Substrate Metadata section

The CodePromise constructor takes 3 arguments: an API instance, the contract metadata, and the contract code. Only the wasm code will end up on-chain; the metadata is only used in the JavaScript world. See Prerequisites to find out how to obtain them.

import { CodePromise } from '@polkadot/api-contract';

const code = new CodePromise(api, metadata, wasm);

The newly generated code object lets you call instantiate_with_code without having to encode the data yourself. You will need to provide values for the instantiation options. Getting accurate gas and storage deposit costs is possible by calling the instantiate RPC, which dry runs the instantiation and returns the outcome. For the scope of this tutorial we will use hardcoded values.

Here is how you would retrieve the contract address after instantiation for an ink! incrementer contract, whose constructor signature looks like this: new (initValue: i32)

// maximum gas to be consumed for the instantiation. if limit is too small the instantiation will fail.
const gasLimit = 100000n * 1000000n
// a limit to how much Balance to be used to pay for the storage created by the instantiation
// if null is passed, unlimited balance can be used
const storageDepositLimit = null
// used to derive contract address,
// use null to prevent duplicate contracts
const salt = new Uint8Array()
// balance to transfer to the contract account, formerly known as "endowment".
// use only with payable constructors, will fail otherwise.
const value = api.registry.createType('Balance', 1000)
const initValue = 1;

const tx = code.tx.new({ gasLimit, storageDepositLimit }, initValue)

let address;

const unsub = await tx.signAndSend(alicePair, ({ contract, status }) => {
if (status.isInBlock || status.isFinalized) {
address = contract.address.toString();
unsub();
}
});

After we have uploaded the WASM on-chain, next we'll use the Blueprint to (re)instantiate on-chain code.