Skip to main content

Nil.js deploying a smart contract

Overview

This tutorial deploys two smart contracts:

  • Retailer.sol: this contract can call a special 'manufacturer' contract and order new products by performing an async call.
  • Manufacturer.sol: this contract can accept orders from the retailer and fulfil them by 'manufacturing' and sending new products.

Internal deployment

tip

When submitting contract bytecode as a string to a deployment transaction, preface it with "0x".

The contract ABI can be copy-pasted from the ./abi file and then cast into the Abi type.

To deploy the retailer contract:

const client = new PublicClient({
transport: new HttpTransport({
endpoint: RPC_ENDPOINT,
}),
shardId: 1,
});

const smartAccount = await generateSmartAccount({
shardId: 1,
rpcEndpoint: RPC_ENDPOINT,
faucetEndpoint: FAUCET_ENDPOINT,
});

const { address: retailerAddress, hash: retailerDeploymentHash } =
await smartAccount.deployContract({
bytecode: RETAILER_BYTECODE,
abi: RETAILER_ABI,
args: [],
value: 0n,
feeCredit: 1_000_000n * gasPrice,
salt: BigInt(Math.floor(Math.random() * 10000)),
shardId: 1,
});

const receiptsRetailer = await waitTillCompleted(client, retailerDeploymentHash);

To deploy the manufacturer contract:


const { address: manufacturerAddress, hash: manufacturerDeploymentHash } =
await smartAccount.deployContract({
bytecode: MANUFACTURER_BYTECODE,
abi: MANUFACTURER_ABI,
args: [bytesToHex(pubkey), retailerAddress],
value: 0n,
feeCredit: 1_000_000n * gasPrice,
salt: BigInt(Math.floor(Math.random() * 10000)),
shardId: 2,
});

const manufacturerReceipts = await waitTillCompleted(client, manufacturerDeploymentHash);

External deployment

tip

When submitting contract bytecode as a string to a deployment transaction, preface it with "0x".

The contract ABI can be copy-pasted from the ./abi file and then cast into the Abi type.

To deploy the retailer contract:

const client = new PublicClient({
transport: new HttpTransport({
endpoint: RPC_ENDPOINT,
}),
shardId: 1,
});

const gasPrice = await client.getGasPrice(1);

const pubkey = getPublicKey(generateRandomPrivateKey());

const chainId = await client.chainId();

const deploymentTransactionRetailer = externalDeploymentTransaction(
{
salt: BigInt(Math.floor(Math.random() * 10000)),
shard: 1,
bytecode: RETAILER_BYTECODE,
feeCredit: 1_000_000n * gasPrice,
},
chainId,
);

const addressRetailer = bytesToHex(deploymentTransactionRetailer.to);

await topUp({
address: addressRetailer,
faucetEndpoint: FAUCET_ENDPOINT,
rpcEndpoint: RPC_ENDPOINT,
});

const receipts = await deploymentTransactionRetailer.send(client);

await waitTillCompleted(client, receipts);

To deploy the manufacturer contract:

const clientTwo = new PublicClient({
transport: new HttpTransport({
endpoint: RPC_ENDPOINT,
}),
shardId: 2,
});

const gasPrice2 = await client.getGasPrice(2);

const deploymentTransactionManufacturer = externalDeploymentTransaction(
{
salt: BigInt(Math.floor(Math.random() * 10000)),
shard: 2,
bytecode: MANUFACTURER_BYTECODE,
abi: MANUFACTURER_ABI,
args: [bytesToHex(pubkey), addressRetailer],
feeCredit: 1_000_000n * gasPrice2,
},
chainId,
);

const addressManufacturer = bytesToHex(deploymentTransactionManufacturer.to);

await topUp({
address: addressManufacturer,
faucetEndpoint: FAUCET_ENDPOINT,
rpcEndpoint: RPC_ENDPOINT,
});

const receiptsManufacturer = await deploymentTransactionManufacturer.send(client);

await waitTillCompleted(clientTwo, receiptsManufacturer);