0
# Contract Instances
1
2
Get contract instances at specific addresses using project artifacts or ABI, with automatic signer binding.
3
4
## Capabilities
5
6
### Get Contract At Address
7
8
Creates a contract instance connected to a specific deployed address.
9
10
```typescript { .api }
11
/**
12
* Get a contract instance at a specific address
13
* @param nameOrAbi - Contract name or ABI array
14
* @param address - Contract deployment address
15
* @param signer - Optional signer to connect to the contract
16
* @returns Promise resolving to Contract instance
17
*/
18
function getContractAt(
19
nameOrAbi: string | any[] | Abi,
20
address: string | ethers.Addressable,
21
signer?: ethers.Signer
22
): Promise<ethers.Contract>;
23
24
type Abi = ReadonlyArray<Fragment>;
25
26
interface Fragment {
27
type: string;
28
name?: string;
29
inputs?: any[];
30
outputs?: any[];
31
stateMutability?: string;
32
}
33
34
interface LinkReferences {
35
[sourceName: string]: {
36
[libraryName: string]: Array<{
37
start: number;
38
length: number;
39
}>;
40
};
41
}
42
```
43
44
**Usage Examples:**
45
46
```typescript
47
import { network } from "hardhat";
48
49
const { ethers } = await network.connect();
50
51
// Connect to contract by name
52
const counter = await ethers.getContractAt("Counter", "0x1234...abcd");
53
54
// Connect with specific signer
55
const [, caller] = await ethers.getSigners();
56
const counter = await ethers.getContractAt("Counter", "0x1234...abcd", caller);
57
58
// Connect using ABI
59
const counterAbi = [
60
"function increment() external",
61
"function count() external view returns (uint256)",
62
];
63
const counter = await ethers.getContractAt(counterAbi, "0x1234...abcd");
64
65
// Connect to contract with Addressable
66
const addressable = { getAddress: () => Promise.resolve("0x1234...abcd") };
67
const counter = await ethers.getContractAt("Counter", addressable);
68
```
69
70
### Get Contract At Address from Artifact
71
72
Creates a contract instance from a Hardhat artifact at a specific address.
73
74
```typescript { .api }
75
/**
76
* Get a contract instance from artifact at specific address
77
* @param artifact - Hardhat artifact containing contract metadata
78
* @param address - Contract deployment address
79
* @param signer - Optional signer to connect to the contract
80
* @returns Promise resolving to Contract instance
81
*/
82
function getContractAtFromArtifact(
83
artifact: Artifact,
84
address: string | ethers.Addressable,
85
signer?: ethers.Signer
86
): Promise<ethers.Contract>;
87
88
interface Artifact<T = any> {
89
contractName: string;
90
sourceName: string;
91
abi: T;
92
bytecode: string;
93
deployedBytecode: string;
94
linkReferences: LinkReferences;
95
deployedLinkReferences: LinkReferences;
96
}
97
```
98
99
**Usage Examples:**
100
101
```typescript
102
import { artifacts } from "hardhat";
103
104
// Load artifact and connect to deployed contract
105
const counterArtifact = await artifacts.readArtifact("Counter");
106
const counter = await ethers.getContractAtFromArtifact(
107
counterArtifact,
108
"0x1234...abcd"
109
);
110
111
// With specific signer
112
const [, caller] = await ethers.getSigners();
113
const counter = await ethers.getContractAtFromArtifact(
114
counterArtifact,
115
"0x1234...abcd",
116
caller
117
);
118
```
119
120
### Automatic Signer Binding
121
122
When no signer is provided, contracts are automatically connected to the first available signer:
123
124
```typescript
125
// These are equivalent when using default signer
126
const counter1 = await ethers.getContractAt("Counter", address);
127
128
const [defaultSigner] = await ethers.getSigners();
129
const counter2 = await ethers.getContractAt("Counter", address, defaultSigner);
130
```
131
132
If no signers are available, the contract is connected to the provider for read-only operations:
133
134
```typescript
135
// Read-only contract (when no signers available)
136
const counter = await ethers.getContractAt("Counter", address);
137
const currentCount = await counter.count(); // Read operations work
138
// counter.increment(); // Would fail - no signer for transactions
139
```
140
141
### Contract Instance Usage
142
143
Once you have a contract instance, use standard ethers.js patterns:
144
145
```typescript
146
const counter = await ethers.getContractAt("Counter", address);
147
148
// Read operations
149
const count = await counter.count();
150
const owner = await counter.owner();
151
152
// Write operations (requires signer)
153
const tx = await counter.increment();
154
await tx.wait();
155
156
// Call with transaction options
157
const tx2 = await counter.increment({
158
gasPrice: ethers.parseUnits("20", "gwei"),
159
gasLimit: 100000,
160
});
161
162
// Connect to different signer
163
const [, newSigner] = await ethers.getSigners();
164
const counterWithNewSigner = counter.connect(newSigner);
165
```
166
167
### Working with Fully Qualified Names
168
169
For contracts with the same name in different files:
170
171
```typescript
172
// Specify full path to disambiguate
173
const counter = await ethers.getContractAt(
174
"contracts/v1/Counter.sol:Counter",
175
address
176
);
177
178
const counterV2 = await ethers.getContractAt(
179
"contracts/v2/Counter.sol:Counter",
180
address
181
);
182
```
183
184
### Error Handling
185
186
The functions will throw errors in these cases:
187
188
- Invalid contract name (not found in artifacts)
189
- Invalid artifact structure
190
- Invalid address format
191
- Network connection issues
192
193
```typescript
194
try {
195
const counter = await ethers.getContractAt("NonExistentContract", address);
196
} catch (error) {
197
console.error("Contract not found:", error.message);
198
}
199
200
try {
201
const counter = await ethers.getContractAt("Counter", "invalid-address");
202
} catch (error) {
203
console.error("Invalid address:", error.message);
204
}
205
```