CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hardhat-deploy

Hardhat plugin providing comprehensive deployment system for Ethereum smart contracts with replicable deployments and enhanced testing capabilities.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

contract-interaction.mddocs/

Contract Interaction

Execute transactions and read contract state using deployed contract names with comprehensive transaction options and error handling.

Capabilities

Execute Transactions

Execute state-changing contract methods with transaction options and receipt handling.

/**
 * Execute a contract method with transaction options
 * @param name - Deployed contract name
 * @param options - Transaction configuration options
 * @param methodName - Contract method name to call
 * @param args - Method arguments
 * @returns Promise resolving to transaction receipt
 */
execute(
  name: string,
  options: TxOptions,
  methodName: string,
  ...args: any[]
): Promise<Receipt>;

interface TxOptions extends CallOptions {
  /** Address to execute transaction from (required) */
  from: string;
  /** Enable transaction logging */
  log?: boolean;
  /** Auto-mine transaction on development networks */
  autoMine?: boolean;
  /** Estimated gas limit for optimization */
  estimatedGasLimit?: string | number | BigNumber;
  /** Extra gas to add to estimates */
  estimateGasExtra?: string | number | BigNumber;
  /** Number of confirmations to wait for */
  waitConfirmations?: number;
}

Usage Examples:

import { deployments, getNamedAccounts } from "hardhat";

// Basic contract execution
const { deployer, user } = await getNamedAccounts();
const receipt = await deployments.execute(
  "MyContract",
  { from: deployer, log: true },
  "setOwner",
  user
);

console.log(`Transaction hash: ${receipt.transactionHash}`);
console.log(`Gas used: ${receipt.gasUsed}`);

// Execute with gas settings
await deployments.execute(
  "HighGasContract",
  {
    from: deployer,
    gasLimit: 1000000,
    gasPrice: ethers.utils.parseUnits("20", "gwei"),
    waitConfirmations: 2,
  },
  "complexOperation",
  "param1",
  "param2",
  42
);

// Execute with value transfer
await deployments.execute(
  "PayableContract",
  {
    from: user,
    value: ethers.utils.parseEther("1.0"),
    log: true,
  },
  "payableFunction",
  "data"
);

// Execute with EIP-1559 gas pricing
await deployments.execute(
  "ModernContract",
  {
    from: deployer,
    maxFeePerGas: ethers.utils.parseUnits("30", "gwei"),
    maxPriorityFeePerGas: ethers.utils.parseUnits("2", "gwei"),
  },
  "modernMethod",
  123
);

Read Contract State

Read contract state without creating transactions, with optional call context.

/**
 * Read contract state using call options
 * @param name - Deployed contract name
 * @param options - Call configuration options
 * @param methodName - Contract method name to call
 * @param args - Method arguments
 * @returns Promise resolving to method return value
 */
read(
  name: string,
  options: CallOptions,
  methodName: string,
  ...args: any[]
): Promise<any>;

/**
 * Read contract state with minimal options
 * @param name - Deployed contract name
 * @param methodName - Contract method name to call
 * @param args - Method arguments
 * @returns Promise resolving to method return value
 */
read(name: string, methodName: string, ...args: any[]): Promise<any>;

interface CallOptions {
  /** Address to call from (optional) */
  from?: string;
  /** Gas limit for the call */
  gasLimit?: string | number | BigNumber;
  /** Gas price for the call */
  gasPrice?: string | BigNumber;
  /** EIP-1559 max fee per gas */
  maxFeePerGas?: string | BigNumber;
  /** EIP-1559 max priority fee per gas */
  maxPriorityFeePerGas?: string | BigNumber;
  /** Ether value to send with call */
  value?: string | BigNumber;
  /** Nonce for the call */
  nonce?: string | number | BigNumber;
  /** Target address (usually not needed) */
  to?: string;
  /** Call data (usually not needed) */
  data?: string;
  /** Custom data for the call */
  customData?: Record<string, any>;
}

Usage Examples:

// Simple read call
const owner = await deployments.read("MyContract", "owner");
console.log(`Current owner: ${owner}`);

// Read with parameters
const balance = await deployments.read(
  "TokenContract",
  "balanceOf",
  "0x1234567890123456789012345678901234567890"
);

// Read with call options
const result = await deployments.read(
  "StatefulContract",
  {
    from: user,
    value: ethers.utils.parseEther("0.1"),
  },
  "simulatePayment",
  "recipient",
  ethers.utils.parseEther("1.0")
);

// Read complex return values
const [amount, timestamp, active] = await deployments.read(
  "ComplexContract",
  "getDetails",
  123
);

console.log(`Amount: ${amount}, Timestamp: ${timestamp}, Active: ${active}`);

// Read struct return values
const userInfo = await deployments.read("UserContract", "getUserInfo", userId);
console.log(`Name: ${userInfo.name}, Score: ${userInfo.score}`);

Raw Transaction Execution

Execute raw transactions with custom data and recipients.

/**
 * Execute a raw transaction
 * @param tx - Transaction configuration
 * @returns Promise resolving to transaction receipt
 */
rawTx(tx: SimpleTx): Promise<Receipt>;

interface SimpleTx extends TxOptions {
  /** Transaction recipient address */
  to: string;
}

Usage Examples:

// Raw transaction to contract
const receipt = await deployments.rawTx({
  from: deployer,
  to: "0x1234567890123456789012345678901234567890",
  data: "0xa9059cbb000000000000000000000000...", // ERC20 transfer
  gasLimit: 21000,
  log: true,
});

// Raw transaction with value
await deployments.rawTx({
  from: user,
  to: "0x9876543210987654321098765432109876543210",
  value: ethers.utils.parseEther("0.5"),
  data: "0x",
  autoMine: true,
});

// Raw transaction with custom gas pricing
await deployments.rawTx({
  from: deployer,
  to: contractAddress,
  data: encodedFunctionCall,
  maxFeePerGas: ethers.utils.parseUnits("25", "gwei"),
  maxPriorityFeePerGas: ethers.utils.parseUnits("1.5", "gwei"),
  waitConfirmations: 3,
});

Signer Management

Access signers for direct contract interaction.

/**
 * Get a signer for the specified address
 * @param address - Address to get signer for
 * @returns Promise resolving to ethers Signer instance
 */
getSigner(address: string): Promise<Signer>;

Usage Examples:

// Get signer for direct contract interaction
const signer = await deployments.getSigner(deployer);
const contract = await deployments.get("MyContract");
const contractInstance = new ethers.Contract(
  contract.address,
  contract.abi,
  signer
);

// Use signer directly
const tx = await contractInstance.someMethod("param");
await tx.wait();

// Get signer for named account
const { user } = await getNamedAccounts();
const userSigner = await deployments.getSigner(user);
const userContractInstance = contractInstance.connect(userSigner);

Error Handling

Handle unknown signers and transaction failures gracefully.

/**
 * Catch and handle unknown signer errors
 * @param action - Promise or function to execute
 * @param options - Configuration options
 * @returns Promise resolving to null or transaction details
 */
catchUnknownSigner(
  action: Promise<any> | (() => Promise<any>),
  options?: { log?: boolean }
): Promise<null | {
  from: string;
  to?: string;
  value?: string;
  data?: string;
}>;

Usage Examples:

// Handle unknown signer gracefully
const result = await deployments.catchUnknownSigner(
  deployments.execute(
    "MyContract",
    { from: "0xunknownsigner..." },
    "someMethod"
  )
);

if (result) {
  console.log("Transaction details for manual execution:");
  console.log(`From: ${result.from}`);
  console.log(`To: ${result.to}`);
  console.log(`Data: ${result.data}`);
}

// Disable logging for unknown signers
await deployments.catchUnknownSigner(
  async () => {
    await deployments.execute(
      "Contract",
      { from: unknownAddress },
      "method"
    );
  },
  { log: false }
);

// Handle deployment with unknown signer
const deployResult = await deployments.catchUnknownSigner(
  deployments.deploy("NewContract", {
    from: "0xmultisigaddress...",
    args: ["arg1", "arg2"],
  })
);

Types

interface Receipt {
  from: Address;
  transactionHash: string;
  blockHash: string;
  blockNumber: number;
  transactionIndex: number;
  cumulativeGasUsed: BigNumber | string | number;
  gasUsed: BigNumber | string | number;
  contractAddress?: string;
  to?: Address;
  logs?: Log[];
  events?: any[];
  logsBloom?: string;
  byzantium?: boolean;
  status?: number;
  confirmations?: number;
}

interface Log {
  blockNumber: number;
  blockHash: string;
  transactionHash: string;
  transactionIndex: number;
  logIndex: number;
  removed: boolean;
  address: string;
  topics: string[];
  data: string;
}

interface TxOptions extends CallOptions {
  from: string;
  log?: boolean;
  autoMine?: boolean;
  estimatedGasLimit?: string | number | BigNumber;
  estimateGasExtra?: string | number | BigNumber;
  waitConfirmations?: number;
}

interface CallOptions {
  from?: string;
  gasLimit?: string | number | BigNumber;
  gasPrice?: string | BigNumber;
  maxFeePerGas?: string | BigNumber;
  maxPriorityFeePerGas?: string | BigNumber;
  value?: string | BigNumber;
  nonce?: string | number | BigNumber;
  to?: string;
  data?: string;
  customData?: Record<string, any>;
}

interface SimpleTx extends TxOptions {
  to: string;
}

type Address = string;

docs

contract-interaction.md

core-deployment.md

deployment-management.md

diamond-deployment.md

index.md

named-accounts.md

proxy-deployment.md

test-fixtures.md

verification.md

tile.json