(rawContents: string)
| 380 | } |
| 381 | |
| 382 | export function extractBytecode(rawContents: string): BytecodeWithLinkReferences | undefined { |
| 383 | // When there are some unlinked libraries, the compiler replaces their addresses in calls with |
| 384 | // "link references". There are many different kinds of those, depending on compiler version and usage. |
| 385 | // Examples: |
| 386 | // * `__TestLibrary___________________________` |
| 387 | // (truffle with solc 0.4.x?, just the contract name) |
| 388 | // * `__./ContractWithLibrary.sol:TestLibrar__` |
| 389 | // (solc 0.4.x, `${fileName}:${contractName}` truncated at 36 chars) |
| 390 | // * `__$8809803722eff063c8527a84f57d60014e$__` |
| 391 | // (solc 0.5.x, ``solidityKeccak256(['string'], [`${fileName}:${contractName}`])``, truncated ) |
| 392 | const bytecodeRegex = /^(0x)?(([0-9a-fA-F][0-9a-fA-F])|(__[a-zA-Z0-9/\\:_$.-]{36}__))+$/ |
| 393 | // First try to see if this is a .bin file with just the bytecode, otherwise a json |
| 394 | if (rawContents.match(bytecodeRegex)) return extractLinkReferences(rawContents) |
| 395 | |
| 396 | let json |
| 397 | try { |
| 398 | json = JSON.parse(rawContents) |
| 399 | } catch { |
| 400 | return undefined |
| 401 | } |
| 402 | |
| 403 | if (!json) return undefined |
| 404 | |
| 405 | function tryMatchBytecode(obj: any | undefined): any | undefined { |
| 406 | if (obj && obj.match instanceof Function) { |
| 407 | return obj.match(bytecodeRegex) |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | // `json.evm.bytecode` often has more information than `json.bytecode`, needs to be checked first |
| 412 | if (tryMatchBytecode(json.evm?.bytecode?.object)) { |
| 413 | return extractLinkReferences(json.evm.bytecode.object, json.evm.bytecode.linkReferences) |
| 414 | } |
| 415 | |
| 416 | // handle json schema of @0x/sol-compiler |
| 417 | if (tryMatchBytecode(json.compilerOutput?.evm?.bytecode?.object)) { |
| 418 | return extractLinkReferences( |
| 419 | json.compilerOutput.evm.bytecode.object, |
| 420 | json.compilerOutput.evm.bytecode.linkReferences, |
| 421 | ) |
| 422 | } |
| 423 | |
| 424 | // handle json schema of @foundry/forge |
| 425 | if (tryMatchBytecode(json.bytecode?.object)) { |
| 426 | return extractLinkReferences(json.bytecode.object, json.bytecode.linkReferences) |
| 427 | } |
| 428 | |
| 429 | if (tryMatchBytecode(json.bytecode)) { |
| 430 | return extractLinkReferences(json.bytecode, json.linkReferences) |
| 431 | } |
| 432 | |
| 433 | return undefined |
| 434 | } |
| 435 | |
| 436 | export function extractDocumentation(rawContents: string): DocumentationResult | undefined { |
| 437 | let json |
no test coverage detected
searching dependent graphs…