or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

contract-interaction.mdcore-deployment.mddeployment-management.mddiamond-deployment.mdindex.mdnamed-accounts.mdproxy-deployment.mdtest-fixtures.mdverification.md
tile.json

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;