0
# Contract Interaction
1
2
Functions for interacting with deployed contracts at specific addresses using contract names, artifacts, or ABI definitions. These functions create contract instances that can call functions on already deployed contracts.
3
4
## Capabilities
5
6
### Get Contract At Address by Name
7
8
Creates a contract instance at a specific address using the contract name from compiled artifacts.
9
10
```typescript { .api }
11
/**
12
* Creates a contract instance at a specific address using contract name
13
* @param name - Contract name as defined in your Solidity files
14
* @param address - Deployed contract address
15
* @param signer - Signer to use for transactions (optional)
16
* @returns Promise resolving to Contract instance
17
*/
18
function getContractAt(
19
name: string,
20
address: string,
21
signer?: ethers.Signer
22
): Promise<ethers.Contract>;
23
```
24
25
**Usage Examples:**
26
27
```typescript
28
import { ethers } from "hardhat";
29
30
// Connect to deployed contract with default signer
31
const contract = await ethers.getContractAt("MyContract", "0x1234567890123456789012345678901234567890");
32
33
// Connect with specific signer
34
const [deployer, user] = await ethers.getSigners();
35
const contract = await ethers.getContractAt("MyContract", contractAddress, user);
36
37
// Call contract functions
38
const result = await contract.someReadFunction();
39
const tx = await contract.someWriteFunction(arg1, arg2);
40
await tx.wait();
41
```
42
43
### Get Contract At Address by ABI
44
45
Creates a contract instance at a specific address using ABI directly, useful when you don't have compiled artifacts.
46
47
```typescript { .api }
48
/**
49
* Creates a contract instance at a specific address using ABI
50
* @param abi - Contract ABI array
51
* @param address - Deployed contract address
52
* @param signer - Signer to use for transactions (optional)
53
* @returns Promise resolving to Contract instance
54
*/
55
function getContractAt(
56
abi: any[],
57
address: string,
58
signer?: ethers.Signer
59
): Promise<ethers.Contract>;
60
```
61
62
**Usage Examples:**
63
64
```typescript
65
import { ethers } from "hardhat";
66
67
const abi = [
68
"function name() public view returns (string memory)",
69
"function symbol() public view returns (string memory)",
70
"function balanceOf(address owner) public view returns (uint256)",
71
"function transfer(address to, uint256 amount) public returns (bool)"
72
];
73
74
const tokenContract = await ethers.getContractAt(abi, tokenAddress);
75
76
// Read token information
77
const name = await tokenContract.name();
78
const symbol = await tokenContract.symbol();
79
const balance = await tokenContract.balanceOf(userAddress);
80
81
// Send transaction
82
const tx = await tokenContract.transfer(recipientAddress, amount);
83
await tx.wait();
84
```
85
86
### Get Contract At Address from Artifact
87
88
Creates a contract instance at a specific address using a Hardhat compilation artifact.
89
90
```typescript { .api }
91
/**
92
* Creates a contract instance at a specific address using Hardhat artifact
93
* @param artifact - Hardhat compilation artifact
94
* @param address - Deployed contract address
95
* @param signer - Signer to use for transactions (optional)
96
* @returns Promise resolving to Contract instance
97
*/
98
function getContractAtFromArtifact(
99
artifact: Artifact,
100
address: string,
101
signer?: ethers.Signer
102
): Promise<ethers.Contract>;
103
```
104
105
**Usage Examples:**
106
107
```typescript
108
import { ethers, artifacts } from "hardhat";
109
110
// Load artifact and create contract instance
111
const artifact = await artifacts.readArtifact("MyContract");
112
const contract = await ethers.getContractAtFromArtifact(artifact, contractAddress);
113
114
// Use with specific signer
115
const [deployer] = await ethers.getSigners();
116
const contract = await ethers.getContractAtFromArtifact(artifact, contractAddress, deployer);
117
```
118
119
## Signer Behavior
120
121
### Default Signer
122
123
When no signer is provided, the functions automatically use the first signer from `getSigners()`:
124
125
```typescript
126
// These are equivalent:
127
const contract1 = await ethers.getContractAt("MyContract", address);
128
129
const [defaultSigner] = await ethers.getSigners();
130
const contract2 = await ethers.getContractAt("MyContract", address, defaultSigner);
131
```
132
133
### Read-Only Contracts
134
135
If no signer is available (empty signers array), `getContractAt` returns read-only contracts connected to the provider:
136
137
```typescript
138
// In environments with no signers, contracts are read-only
139
const contract = await ethers.getContractAt("MyContract", address);
140
141
// Can call view/pure functions
142
const result = await contract.someViewFunction();
143
144
// Cannot send transactions (will throw error)
145
// const tx = await contract.someWriteFunction(); // This would fail
146
```
147
148
### Connecting Different Signers
149
150
You can connect the same contract instance to different signers:
151
152
```typescript
153
import { ethers } from "hardhat";
154
155
const [deployer, user1, user2] = await ethers.getSigners();
156
157
// Create initial contract instance
158
const contract = await ethers.getContractAt("MyContract", address, deployer);
159
160
// Connect to different signers
161
const contractAsUser1 = contract.connect(user1);
162
const contractAsUser2 = contract.connect(user2);
163
164
// Each instance uses its connected signer for transactions
165
await contractAsUser1.someFunction(); // Sent by user1
166
await contractAsUser2.someFunction(); // Sent by user2
167
```
168
169
## Contract Instance Usage
170
171
### Calling View Functions
172
173
View and pure functions don't require gas and return values directly:
174
175
```typescript
176
const contract = await ethers.getContractAt("ERC20", tokenAddress);
177
178
// Simple view function
179
const name = await contract.name();
180
const symbol = await contract.symbol();
181
const totalSupply = await contract.totalSupply();
182
183
// View function with parameters
184
const balance = await contract.balanceOf(userAddress);
185
const allowance = await contract.allowance(owner, spender);
186
```
187
188
### Sending Transactions
189
190
State-changing functions require gas and return transaction objects:
191
192
```typescript
193
const contract = await ethers.getContractAt("ERC20", tokenAddress);
194
195
// Send transaction
196
const tx = await contract.transfer(recipientAddress, amount);
197
198
// Wait for transaction to be mined
199
const receipt = await tx.wait();
200
console.log("Transaction hash:", tx.hash);
201
console.log("Block number:", receipt.blockNumber);
202
203
// Transaction with overrides
204
const tx = await contract.transfer(recipientAddress, amount, {
205
gasLimit: 100000,
206
gasPrice: ethers.utils.parseUnits("20", "gwei")
207
});
208
```
209
210
### Event Handling
211
212
Listen to contract events:
213
214
```typescript
215
const contract = await ethers.getContractAt("ERC20", tokenAddress);
216
217
// Listen to Transfer events
218
contract.on("Transfer", (from, to, amount, event) => {
219
console.log(`Transfer: ${from} -> ${to}, Amount: ${amount.toString()}`);
220
});
221
222
// Query past events
223
const filter = contract.filters.Transfer(null, userAddress); // Transfers to userAddress
224
const events = await contract.queryFilter(filter, startBlock, endBlock);
225
```
226
227
## Error Handling
228
229
The contract interaction functions will throw `NomicLabsHardhatPluginError` in the following cases:
230
231
- **Contract not found**: When the specified contract name doesn't exist in compiled artifacts
232
- **Invalid artifact**: When the provided artifact is not a valid Hardhat compilation artifact
233
- **Invalid address**: When the provided address is not a valid Ethereum address
234
- **Network connection issues**: When unable to connect to the blockchain network
235
236
Contract function calls can also throw standard ethers.js errors:
237
238
- **Contract function doesn't exist**: When calling a function not defined in the ABI
239
- **Invalid parameters**: When providing wrong number or type of parameters
240
- **Transaction reverted**: When a transaction fails during execution
241
- **Insufficient gas**: When transaction runs out of gas