or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

artifact-management.mdbuidlerevm-provider.mdbuiltin-tasks.mdconfiguration.mdindex.mdplugin-system.mdtask-system.md

artifact-management.mddocs/

0

# Artifact Management

1

2

Buidler's artifact management system handles compilation artifacts from Solidity contracts, providing utilities for reading, writing, and processing contract compilation results including ABI, bytecode, and metadata.

3

4

## Capabilities

5

6

### Artifact Structure

7

8

Standard artifact format containing all contract compilation information.

9

10

```typescript { .api }

11

/**

12

* Contract compilation artifact

13

*/

14

interface Artifact {

15

/** Contract name */

16

contractName: string;

17

/** Contract ABI (Application Binary Interface) */

18

abi: any;

19

/** Contract creation bytecode (0x-prefixed hex string) */

20

bytecode: string;

21

/** Contract runtime bytecode (0x-prefixed hex string) */

22

deployedBytecode: string;

23

/** Library link references in creation bytecode */

24

linkReferences: LinkReferences;

25

/** Library link references in deployed bytecode */

26

deployedLinkReferences: LinkReferences;

27

}

28

29

/**

30

* Library link references for contract libraries

31

*/

32

interface LinkReferences {

33

[libraryFileName: string]: {

34

[libraryName: string]: Array<{

35

/** Length of placeholder in bytes */

36

length: number;

37

/** Start position of placeholder */

38

start: number;

39

}>;

40

};

41

}

42

```

43

44

### Artifact Reading

45

46

Read contract artifacts from the artifacts directory.

47

48

```typescript { .api }

49

/**

50

* Asynchronously read an artifact by contract name

51

* @param artifactsPath - Path to artifacts directory

52

* @param contractName - Name of the contract

53

* @returns Promise resolving to contract artifact

54

* @throws BuidlerError if artifact not found

55

*/

56

function readArtifact(

57

artifactsPath: string,

58

contractName: string

59

): Promise<Artifact>;

60

61

/**

62

* Synchronously read an artifact by contract name

63

* @param artifactsPath - Path to artifacts directory

64

* @param contractName - Name of the contract

65

* @returns Contract artifact

66

* @throws BuidlerError if artifact not found

67

*/

68

function readArtifactSync(

69

artifactsPath: string,

70

contractName: string

71

): Artifact;

72

```

73

74

**Usage Examples:**

75

76

```typescript

77

import { readArtifact, readArtifactSync } from "@nomiclabs/buidler/plugins";

78

79

// Async reading

80

task("deploy", async (taskArgs, hre) => {

81

const artifact = await readArtifact(hre.config.paths.artifacts, "MyContract");

82

83

console.log("Contract:", artifact.contractName);

84

console.log("ABI:", artifact.abi);

85

console.log("Bytecode length:", artifact.bytecode.length);

86

87

// Use artifact for deployment

88

const contract = new web3.eth.Contract(artifact.abi);

89

const deployment = await contract.deploy({

90

data: artifact.bytecode,

91

arguments: [/* constructor args */]

92

}).send({ from: accounts[0] });

93

});

94

95

// Sync reading (for utility functions)

96

function getContractABI(contractName: string): any {

97

const artifact = readArtifactSync("./artifacts", contractName);

98

return artifact.abi;

99

}

100

101

// Error handling

102

try {

103

const artifact = await readArtifact("./artifacts", "NonExistent");

104

} catch (error) {

105

if (error.message.includes("NOT_FOUND")) {

106

console.log("Contract artifact not found - compile first");

107

}

108

}

109

```

110

111

### Artifact Writing

112

113

Save compilation artifacts to the artifacts directory.

114

115

```typescript { .api }

116

/**

117

* Save an artifact to the artifacts directory

118

* @param artifactsPath - Path to artifacts directory

119

* @param artifact - Artifact to save

120

* @returns Promise that resolves when artifact is saved

121

*/

122

function saveArtifact(

123

artifactsPath: string,

124

artifact: Artifact

125

): Promise<void>;

126

```

127

128

**Usage Examples:**

129

130

```typescript

131

import { saveArtifact } from "@nomiclabs/buidler/plugins";

132

133

// Save custom artifact

134

task("save-custom-artifact", async (taskArgs, hre) => {

135

const customArtifact: Artifact = {

136

contractName: "CustomContract",

137

abi: [

138

{

139

"inputs": [],

140

"name": "test",

141

"outputs": [],

142

"stateMutability": "pure",

143

"type": "function"

144

}

145

],

146

bytecode: "0x608060405234801561001057600080fd5b50...",

147

deployedBytecode: "0x608060405234801561001057600080fd5b50...",

148

linkReferences: {},

149

deployedLinkReferences: {}

150

};

151

152

await saveArtifact(hre.config.paths.artifacts, customArtifact);

153

console.log("Custom artifact saved");

154

});

155

156

// Process and save modified artifact

157

task("optimize-artifact", async (taskArgs, hre) => {

158

const original = await readArtifact(hre.config.paths.artifacts, "MyContract");

159

160

// Create optimized version

161

const optimized: Artifact = {

162

...original,

163

contractName: `${original.contractName}_Optimized`,

164

// Apply optimizations to bytecode

165

bytecode: optimizeBytecode(original.bytecode),

166

deployedBytecode: optimizeBytecode(original.deployedBytecode)

167

};

168

169

await saveArtifact(hre.config.paths.artifacts, optimized);

170

});

171

```

172

173

### Manual Artifact Creation

174

175

Create artifacts manually when needed for custom compilation workflows.

176

177

**Usage Examples:**

178

179

```typescript

180

// Custom compilation task with manual artifact creation

181

task("custom-compile", async (taskArgs, hre) => {

182

const solc = require("solc");

183

184

// Prepare compiler input

185

const input = {

186

language: "Solidity",

187

sources: {

188

"MyContract.sol": {

189

content: fs.readFileSync("contracts/MyContract.sol", "utf8")

190

}

191

},

192

settings: {

193

outputSelection: {

194

"*": {

195

"*": ["abi", "evm.bytecode", "evm.deployedBytecode"]

196

}

197

}

198

}

199

};

200

201

// Compile

202

const output = JSON.parse(solc.compile(JSON.stringify(input)));

203

204

// Convert to artifacts manually

205

for (const sourceFile in output.contracts) {

206

for (const contractName in output.contracts[sourceFile]) {

207

const contractOutput = output.contracts[sourceFile][contractName];

208

209

// Manually create artifact from compiler output

210

const artifact: Artifact = {

211

contractName,

212

abi: contractOutput.abi,

213

bytecode: contractOutput.evm.bytecode.object,

214

deployedBytecode: contractOutput.evm.deployedBytecode.object,

215

linkReferences: contractOutput.evm.bytecode.linkReferences || {},

216

deployedLinkReferences: contractOutput.evm.deployedBytecode.linkReferences || {}

217

};

218

219

await saveArtifact(hre.config.paths.artifacts, artifact);

220

console.log(`Saved artifact for ${contractName}`);

221

}

222

}

223

});

224

```

225

226

### Runtime Environment Integration

227

228

Access artifacts through the Buidler runtime environment.

229

230

**Usage Examples:**

231

232

```typescript

233

// Extend environment with artifact utilities

234

extendEnvironment((hre) => {

235

hre.artifacts = {

236

readArtifact: async (contractName: string) => {

237

return readArtifact(hre.config.paths.artifacts, contractName);

238

},

239

240

readArtifactSync: (contractName: string) => {

241

return readArtifactSync(hre.config.paths.artifacts, contractName);

242

},

243

244

saveArtifact: async (artifact: Artifact) => {

245

return saveArtifact(hre.config.paths.artifacts, artifact);

246

}

247

};

248

});

249

250

// Use in tasks

251

task("contract-info", async (taskArgs, hre) => {

252

const artifact = await hre.artifacts.readArtifact("MyContract");

253

254

console.log("Contract Information:");

255

console.log(`Name: ${artifact.contractName}`);

256

console.log(`Functions: ${artifact.abi.filter(item => item.type === 'function').length}`);

257

console.log(`Events: ${artifact.abi.filter(item => item.type === 'event').length}`);

258

console.log(`Bytecode size: ${(artifact.bytecode.length - 2) / 2} bytes`);

259

260

// Check for libraries

261

const hasLibraries = Object.keys(artifact.linkReferences).length > 0;

262

if (hasLibraries) {

263

console.log("Required libraries:", Object.keys(artifact.linkReferences));

264

}

265

});

266

```

267

268

### Artifact Processing Utilities

269

270

Common utilities for working with artifacts.

271

272

**Usage Examples:**

273

274

```typescript

275

// Extract function signatures

276

function getFunctionSignatures(artifact: Artifact): string[] {

277

return artifact.abi

278

.filter(item => item.type === 'function')

279

.map(func => {

280

const inputs = func.inputs.map(input => input.type).join(',');

281

return `${func.name}(${inputs})`;

282

});

283

}

284

285

// Get contract size

286

function getContractSize(artifact: Artifact): { creation: number; deployed: number } {

287

return {

288

creation: (artifact.bytecode.length - 2) / 2,

289

deployed: (artifact.deployedBytecode.length - 2) / 2

290

};

291

}

292

293

// Check if contract needs libraries

294

function requiresLibraries(artifact: Artifact): boolean {

295

return Object.keys(artifact.linkReferences).length > 0 ||

296

Object.keys(artifact.deployedLinkReferences).length > 0;

297

}

298

299

// Usage in task

300

task("analyze-contracts", async (taskArgs, hre) => {

301

const contractNames = ["Token", "Crowdsale", "Vault"];

302

303

for (const name of contractNames) {

304

const artifact = await hre.artifacts.readArtifact(name);

305

const signatures = getFunctionSignatures(artifact);

306

const size = getContractSize(artifact);

307

const needsLibs = requiresLibraries(artifact);

308

309

console.log(`\n${name}:`);

310

console.log(` Functions: ${signatures.length}`);

311

console.log(` Size: ${size.deployed} bytes`);

312

console.log(` Needs libraries: ${needsLibs}`);

313

314

if (signatures.length < 10) {

315

console.log(` Signatures: ${signatures.join(', ')}`);

316

}

317

}

318

});

319

```

320

321

### Error Handling

322

323

Handle common artifact-related errors gracefully.

324

325

**Usage Examples:**

326

327

```typescript

328

import { BuidlerError } from "@nomiclabs/buidler/plugins";

329

330

task("safe-read-artifact", async (taskArgs, hre) => {

331

try {

332

const artifact = await readArtifact(hre.config.paths.artifacts, taskArgs.contract);

333

console.log("Artifact loaded successfully");

334

return artifact;

335

} catch (error) {

336

if (error instanceof BuidlerError && error.number === 'ARTIFACTS_NOT_FOUND') {

337

console.log("Artifact not found. Compiling contracts...");

338

await hre.run("compile");

339

340

// Retry after compilation

341

return readArtifact(hre.config.paths.artifacts, taskArgs.contract);

342

} else {

343

console.error("Unexpected error:", error.message);

344

throw error;

345

}

346

}

347

});

348

349

// Batch artifact operations with error handling

350

task("batch-process-artifacts", async (taskArgs, hre) => {

351

const contractNames = ["Token", "Crowdsale", "NonExistent"];

352

const results = [];

353

354

for (const name of contractNames) {

355

try {

356

const artifact = await readArtifact(hre.config.paths.artifacts, name);

357

results.push({ name, success: true, artifact });

358

} catch (error) {

359

results.push({ name, success: false, error: error.message });

360

}

361

}

362

363

// Report results

364

const successful = results.filter(r => r.success);

365

const failed = results.filter(r => !r.success);

366

367

console.log(`Processed ${successful.length} artifacts successfully`);

368

if (failed.length > 0) {

369

console.log(`Failed to process: ${failed.map(f => f.name).join(", ")}`);

370

}

371

});

372

```