Web3 by Example: Deploying a Smart Contract

To deploy a Contract, additional information is needed that is not available on a Contract object itself.

Mainly, the bytecode (more specifically the initcode) of a contract is required.

In previous example, we have compiled the contract and got the abi and bytecode.

Create a wallet that can sign transactions.

Create a new instance of a ContractFactory for the contract described by the interface and bytecode initcode. The Contract Factory sends a special type of transaction, an initcode transaction (i.e. the to field is null, and the data field is the initcode) where the initcode will be evaluated and the result becomes the new code to be deployed as a new contract.

Deploy an instance of the contract. The address is available immediately, but the contract is NOT deployed yet.

Wait until the transaction is mined (i.e. contract is deployed)

- returns the receipt

- throws on failure (the reciept is on the error)

deploy-contract.js

const { ethers } = require("ethers");
const fs = require("fs");
(async () => {
const abi = JSON.parse(fs.readFileSync("storage_sol_SimpleStorage.abi"));
const bytecode = fs.readFileSync("storage_sol_SimpleStorage.bin").toString();
const privateKey = fs.readFileSync("privatekey").toString();
const provider = new ethers.providers.AlchemyProvider("goerli");
const wallet = new ethers.Wallet(privateKey, provider);
const factory = new ethers.ContractFactory(abi, bytecode, wallet);
const contract = await factory.deploy("Hello, world!");
console.log("address", contract.address);
const receipt = await contract.deployTransaction.wait();
console.log("receipt", receipt);
})();

output

➜ node deploy-contract.js
address 0x4deA5308A17Bc20589802f3E2C23e79Ba044d497
receipt {
to: null,
from: '0x67CF3bF40b2b3b3D68F6c361AEf81F8AEb2dB637',
contractAddress: '0x4deA5308A17Bc20589802f3E2C23e79Ba044d497',
transactionIndex: 2,
gasUsed: BigNumber { _hex: '0x0635bd', _isBigNumber: true },
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
blockHash: '0x9282b3f9a6868cf81c5252f949d161cf03a45ae15708030e24dab28467b667ad',
transactionHash: '0xe0708303bd21a508314ef0c3f3b6cc6b628f5bae43347b0f5466b0c2b8af895f',
logs: [],
blockNumber: 6499060,
confirmations: 1,
cumulativeGasUsed: BigNumber { _hex: '0x0a238f', _isBigNumber: true },
effectiveGasPrice: BigNumber { _hex: '0x9502f909', _isBigNumber: true },
status: 1,
type: 2,
byzantium: true,
events: []
}

Next example: Loading a Smart Contract