-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability for ArtifactManager to identify contracts without metadat…
…a hash; Add tests for contract liftime transformer
- Loading branch information
Showing
8 changed files
with
5,530 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { equalsBytes, hexToBytes } from "@ethereumjs/util"; | ||
import { PartialBytecodeDescription, RangeList } from "../../artifacts"; | ||
|
||
export interface BytecodeTemplate { | ||
object: Uint8Array; | ||
skipRanges: Array<[number, number]>; | ||
} | ||
|
||
function makeSkipRanges(rawList: RangeList): Array<[number, number]> { | ||
return rawList.map((raw) => [raw.start, raw.start + raw.length]); | ||
} | ||
|
||
export function makeTemplate(artifact: PartialBytecodeDescription): BytecodeTemplate { | ||
const skipRanges: Array<[number, number]> = []; | ||
|
||
if (artifact.linkReferences) { | ||
for (const obj of Object.values(artifact.linkReferences)) { | ||
for (const ranges of Object.values(obj)) { | ||
skipRanges.push(...makeSkipRanges(ranges)); | ||
} | ||
} | ||
} | ||
|
||
if (artifact.immutableReferences) { | ||
for (const ranges of Object.values(artifact.immutableReferences)) { | ||
skipRanges.push(...makeSkipRanges(ranges)); | ||
} | ||
} | ||
|
||
skipRanges.sort(); | ||
|
||
return { | ||
object: hexToBytes("0x" + artifact.object), | ||
skipRanges | ||
}; | ||
} | ||
|
||
export function matchesTemplate(bytecode: Uint8Array, template: BytecodeTemplate): boolean { | ||
if (bytecode.length !== template.object.length) { | ||
return false; | ||
} | ||
|
||
let curIdx = 0; | ||
let rangeIdx = 0; | ||
|
||
while (curIdx < template.object.length) { | ||
let nextIdx: number; | ||
let compEnd: number; | ||
|
||
if (rangeIdx < template.skipRanges.length) { | ||
[compEnd, nextIdx] = template.skipRanges[rangeIdx]; | ||
} else { | ||
compEnd = nextIdx = template.object.length; | ||
} | ||
|
||
if (!equalsBytes(bytecode.slice(curIdx, compEnd), template.object.slice(curIdx, compEnd))) { | ||
return false; | ||
} | ||
|
||
curIdx = nextIdx; | ||
rangeIdx++; | ||
} | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./artifact_manager"; |
4,748 changes: 4,748 additions & 0 deletions
4,748
test/samples/local/contract_lifetime/artifacts/main.json
Large diffs are not rendered by default.
Oops, something went wrong.
29 changes: 29 additions & 0 deletions
29
test/samples/local/contract_lifetime/contracts/contracts/contract_lifetime.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
pragma solidity 0.8.21; | ||
|
||
contract FailingConstructor { | ||
constructor() public { | ||
revert(); | ||
} | ||
} | ||
|
||
contract Killable { | ||
function die() public { | ||
selfdestruct(payable(0x0)); | ||
} | ||
} | ||
|
||
contract NestedCreation is Killable { | ||
Killable k; | ||
constructor() public { | ||
k = new Killable(); | ||
} | ||
} | ||
|
||
contract NestedCreationFail is Killable { | ||
constructor() public { | ||
try new FailingConstructor() returns (FailingConstructor k) {} catch { | ||
// nada | ||
} | ||
Killable k = new Killable(); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
test/samples/local/contract_lifetime/contracts/hardhat.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
require("@nomicfoundation/hardhat-ethers"); | ||
/** | ||
* @type import('hardhat/config').HardhatUserConfig | ||
*/ | ||
module.exports = { | ||
solidity: "0.8.21", | ||
networks: { | ||
localhost: { | ||
url: "http://localhost:7545" | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { ethers } from "hardhat"; | ||
|
||
(async function main() { | ||
const FailingConstructor = await ethers.getContractFactory("FailingConstructor"); | ||
|
||
const tx = await FailingConstructor.getDeployTransaction(); | ||
console.error("FailingConstructor bytecode:", tx.data); | ||
|
||
// Failing constructor | ||
try { | ||
const t = await FailingConstructor.deploy(); | ||
await t.wait(); | ||
} catch (e) { | ||
console.error(`Failed as expected`); | ||
} | ||
|
||
// Working constructor | ||
const Killable = await ethers.getContractFactory("Killable"); | ||
const killable = await Killable.deploy(); | ||
|
||
console.error("Killable bytecode:", await Killable.getDeployTransaction()); | ||
console.error(`Deployed Killable at `, await killable.getAddress()); | ||
|
||
// Self-destruct | ||
const t = await killable.die(); | ||
console.error(`Die tx: `, t); | ||
|
||
// Nested creation | ||
const NestedCreation = await ethers.getContractFactory("NestedCreation"); | ||
const nestedCreation = await NestedCreation.deploy(); | ||
|
||
console.error("NestedCreation bytecode:", await NestedCreation.getDeployTransaction()); | ||
console.error(`Deployed nested creation at `, await nestedCreation.getAddress()); | ||
// Nested creation with failure | ||
const NestedCreationFail = await ethers.getContractFactory("NestedCreationFail"); | ||
const nestedCreationFail = await NestedCreationFail.deploy(); | ||
|
||
console.error("NestedCreationFail bytecode:", await NestedCreationFail.getDeployTransaction()); | ||
console.error(`Deployed nested creation fail at `, await nestedCreationFail.getAddress()); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
{ | ||
"initialState": { | ||
"accounts": { | ||
"0xAaaaAaAAaaaAAaAAaAaaaaAAAAAaAaaaAaAaaAA0": { | ||
"nonce": 0, | ||
"balance": "0x0000000000000000000000f000000000", | ||
"code": "", | ||
"storage": {} | ||
}, | ||
"0xAaAaaAAAaAaaAaAaAaaAAaAaAAAAAaAAAaaAaAa2": { | ||
"nonce": 0, | ||
"balance": "0x0000000000000000000000f000000000", | ||
"code": "", | ||
"storage": {} | ||
}, | ||
"0xafFEaFFEAFfeAfFEAffeaFfEAfFEaffeafFeAFfE": { | ||
"nonce": 0, | ||
"balance": "0x0000000000000000000000f000000000", | ||
"code": "", | ||
"storage": {} | ||
} | ||
} | ||
}, | ||
"steps": [ | ||
{ | ||
"address": "0x0000000000000000000000000000000000000000", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x6080604052348015600e575f80fd5b5f80fdfe", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 1, | ||
"blockTime": 1, | ||
"result": { | ||
"kind": "revert" | ||
}, | ||
"liveContracts": [] | ||
}, | ||
{ | ||
"address": "0x0000000000000000000000000000000000000000", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x6080604052348015600e575f80fd5b5060818061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806335f4699414602a575b5f80fd5b60306032565b005b5f73ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220aac49067c690fc4a7a711ec18c9a8b6accf3004cea6deef0a7f51a029997a97e64736f6c63430008150033", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 1, | ||
"blockTime": 1, | ||
"result": { | ||
"kind": "contract_created", | ||
"address": "0x1faca6f2f8e169c54e0b1fe6d889dfc21ab5737e" | ||
}, | ||
"liveContracts": [] | ||
}, | ||
{ | ||
"address": "0x1faca6f2f8e169c54e0b1fe6d889dfc21ab5737e", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x35f46994", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 2, | ||
"blockTime": 2, | ||
"result": { | ||
"kind": "value_returned", | ||
"value": "" | ||
}, | ||
"liveContracts": ["0x1faca6f2f8e169c54e0b1fe6d889dfc21ab5737e"] | ||
}, | ||
{ | ||
"address": "0x0000000000000000000000000000000000000000", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x608060405234801561000f575f80fd5b5060405161001c90610079565b604051809103905ff080158015610035573d5f803e3d5ffd5b505f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610085565b609c8061011283390190565b6081806100915f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806335f4699414602a575b5f80fd5b60306032565b005b5f73ffffffffffffffffffffffffffffffffffffffff16fffea264697066735822122022b5ad5f782b0bc41d4425d4f3537930800b64da0c6d3808b7c1cfc35533989364736f6c634300081500336080604052348015600e575f80fd5b5060818061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806335f4699414602a575b5f80fd5b60306032565b005b5f73ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220aac49067c690fc4a7a711ec18c9a8b6accf3004cea6deef0a7f51a029997a97e64736f6c63430008150033", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 1, | ||
"blockTime": 1, | ||
"result": { | ||
"kind": "contract_created", | ||
"address": "0x66d9baa1e8afa844766e15103b3b2a533304af5b" | ||
}, | ||
"liveContracts": [] | ||
}, | ||
{ | ||
"address": "0x0000000000000000000000000000000000000000", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x608060405234801561000f575f80fd5b5060405161001c90610064565b604051809103905ff0801561002e5760015b1561003557505b5f60405161004290610070565b604051809103905ff08015801561005b573d5f803e3d5ffd5b5090505061007c565b60138061010983390190565b609c8061011c83390190565b6081806100885f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806335f4699414602a575b5f80fd5b60306032565b005b5f73ffffffffffffffffffffffffffffffffffffffff16fffea264697066735822122005e088379ce3c7f9582da2f32848f32e2a0e0351d10b82981d122e2f0ac9963664736f6c634300081500336080604052348015600e575f80fd5b5f80fdfe6080604052348015600e575f80fd5b5060818061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806335f4699414602a575b5f80fd5b60306032565b005b5f73ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220aac49067c690fc4a7a711ec18c9a8b6accf3004cea6deef0a7f51a029997a97e64736f6c63430008150033", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 1, | ||
"blockTime": 1, | ||
"result": { | ||
"kind": "contract_created", | ||
"address": "0x8d57cb6b2c9889b43514e729b70c17d7afb8227c" | ||
}, | ||
"liveContracts": [ | ||
"0x66d9baa1e8afa844766e15103b3b2a533304af5b", | ||
"0x5706659cf82b70d4b805ba2e9540cbc1b60fec22" | ||
] | ||
}, | ||
{ | ||
"address": "0x8d57cb6b2c9889b43514e729b70c17d7afb8227c", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x35f46994", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 2, | ||
"blockTime": 2, | ||
"result": { | ||
"kind": "value_returned", | ||
"value": "" | ||
}, | ||
"liveContracts": [ | ||
"0x5706659cf82b70d4b805ba2e9540cbc1b60fec22", | ||
"0x66d9baa1e8afa844766e15103b3b2a533304af5b", | ||
"0x8d57cb6b2c9889b43514e729b70c17d7afb8227c", | ||
"0x99ef7cc5214b804f7ffba13c70a2d7c2f9763d60" | ||
] | ||
}, | ||
{ | ||
"address": "0x5706659cf82b70d4b805ba2e9540cbc1b60fec22", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x35f46994", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 2, | ||
"blockTime": 2, | ||
"result": { | ||
"kind": "value_returned", | ||
"value": "" | ||
}, | ||
"liveContracts": [ | ||
"0x5706659cf82b70d4b805ba2e9540cbc1b60fec22", | ||
"0x66d9baa1e8afa844766e15103b3b2a533304af5b", | ||
"0x99ef7cc5214b804f7ffba13c70a2d7c2f9763d60" | ||
] | ||
}, | ||
{ | ||
"address": "0x66d9baa1e8afa844766e15103b3b2a533304af5b", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x35f46994", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 2, | ||
"blockTime": 2, | ||
"result": { | ||
"kind": "value_returned", | ||
"value": "" | ||
}, | ||
"liveContracts": [ | ||
"0x66d9baa1e8afa844766e15103b3b2a533304af5b", | ||
"0x99ef7cc5214b804f7ffba13c70a2d7c2f9763d60" | ||
] | ||
}, | ||
{ | ||
"address": "0x99ef7cc5214b804f7ffba13c70a2d7c2f9763d60", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x35f46994", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 2, | ||
"blockTime": 2, | ||
"result": { | ||
"kind": "value_returned", | ||
"value": "" | ||
}, | ||
"liveContracts": ["0x99ef7cc5214b804f7ffba13c70a2d7c2f9763d60"] | ||
}, | ||
{ | ||
"address": "0x99ef7cc5214b804f7ffba13c70a2d7c2f9763d60", | ||
"gasLimit": "0xff0000", | ||
"gasPrice": "0x1", | ||
"input": "0x35f46994", | ||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"value": "0x0", | ||
"blockCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0", | ||
"blockDifficulty": "0xc", | ||
"blockGasLimit": "0xff0000", | ||
"blockNumber": 2, | ||
"blockTime": 2, | ||
"result": { | ||
"kind": "value_returned", | ||
"value": "" | ||
}, | ||
"liveContracts": [] | ||
} | ||
] | ||
} |