{"_id":"@bradthomasbrown/evm-multi-context","name":"@bradthomasbrown/evm-multi-context","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@bradthomasbrown/evm-multi-context","description":"An implementation of a multi-context Ethereum virtual machine (EVM) in JavaScript/TypeScript.","version":"1.0.0","author":{"name":"Brad Brown","email":"https://t.me/bradthomasbrown"},"type":"module","exports":{".":"./dist/machine.js"},"dependencies":{"@bradthomasbrown/evm-single-context":"^1.1.1","@bradthomasbrown/machine":"^1.0.0"},"devDependencies":{"@types/bun":"^1.3.5"},"gitHead":"7b44c485f7ffc60ab36e067a51e0791a2a3d1f19","_id":"@bradthomasbrown/evm-multi-context@1.0.0","_nodeVersion":"22.16.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-wuS2V2Y0XuaJtwyQNnT0VD07OVYqkRkyaxJpAajnl0W9wRbqcBz5m0HzDIieguT0e1FaZVfBEKEJ/gkFQv9TKw==","shasum":"5f1167a70f6f2be981fb69225fd644c685a4ad59","tarball":"https://registry.npmjs.org/@bradthomasbrown/evm-multi-context/-/evm-multi-context-1.0.0.tgz","fileCount":5,"unpackedSize":11630,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDKCPNqHV7p5jjFv5fXvEbpPYdsgKiOU8U4uz97RHaLqAIgVav/iIqHHe5OHcRRUIFi7sArs2eCaOJ9rTlqU6eQ2z8="}]},"_npmUser":{"name":"bradthomasbrown","email":"bradthomasbrown@outlook.com"},"directories":{},"maintainers":[{"name":"bradthomasbrown","email":"bradthomasbrown@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/evm-multi-context_1.0.0_1768884164483_0.28828815772305894"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-20T04:42:44.380Z","1.0.0":"2026-01-20T04:42:44.628Z","modified":"2026-01-20T04:42:44.862Z"},"maintainers":[{"name":"bradthomasbrown","email":"bradthomasbrown@outlook.com"}],"description":"An implementation of a multi-context Ethereum virtual machine (EVM) in JavaScript/TypeScript.","author":{"name":"Brad Brown","email":"https://t.me/bradthomasbrown"},"readme":"# evm-multi-context\r\nThis is an implementation of a \"multi-context machine\" partial interpretation of an Ethereum Virtual Machine (EVM). \r\nBy \"multi-context machine\", we mean that an instance of one of these machines will run, create, and destroy multiple single-context machines until a transaction is complete, sort of a \"thunk-like\" replacement for typical EVM execution recursion.\r\n\r\n## Why?\r\nIt was necessary to extend the single-context machine functionality to handle transactions and doing it this way allows single steps and execution pauses even in deeply recursive situations. Although, I don't know if such things aren't possible in the typical recursive way of doing this, this just happened to be more or less how I found it intuitive to deal with this.\r\n\r\n## Installation\r\n```sh\r\nnpm i @bradthomasbrown/evm-multi-context\r\n```\r\n\r\n## Usage\r\n```js\r\nimport type { Context as _589bc4_ } from \"@bradthomasbrown/evm-single-context/types\";\r\nimport { createContext, getStateValue } from \"@bradthomasbrown/evm-single-context/lib\";\r\nimport { SingleContextMachine, traceObjects } from \"@bradthomasbrown/evm-single-context\";\r\nimport { MultiContextMachine } from \"./src/machine\";\r\n\r\nconst states:_589bc4_[\"states\"] = [{ accounts:new Map(), transientStorage:null, storage:null }];\r\n\r\n// deterministic deployer transaction\r\nconst _63_ = {\r\n    hash: \"0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26\",\r\n    blockHash: \"0xdaa690a16bc4a2bf2ff8955ff1cf3bc2155bc9c53f5731b6f8706fdc2b33b82c\",\r\n    blockNumber: 10670819n,\r\n    from: \"0x3fab184622dc19b6109349b94811493bf2a45362\",\r\n    gas: 100000n,\r\n    gasPrice: 100000000000n,\r\n    input: \"0x604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\",\r\n    nonce: 0n,\r\n    to: null,\r\n    transactionIndex: 42n,\r\n    value: 0n,\r\n    v: 27n,\r\n    r: 15438945231642159389809464667825054380435997955418741871927677867721750618658n,\r\n    s: 15438945231642159389809464667825054380435997955418741871927677867721750618658n,\r\n};\r\n\r\nconsole.log({ _63_ });\r\nstates[0].accounts!.set(_63_.from, { nonce: 1n, balance: 0n, code: null });\r\n\r\n// deploy the deterministic deployer\r\nconst _af_ = createContext({\r\n    states,\r\n    origin: _63_.from,\r\n    sender: _63_.from,\r\n    to: _63_.to,\r\n    calldata: Uint8Array.fromHex(_63_.input.slice(2)).buffer,\r\n    gas: 100_000_000n,\r\n    value: _63_.value\r\n});\r\nconst _34_ = new SingleContextMachine(_af_);\r\nconst _ca_:InstanceType<typeof MultiContextMachine>[\"context\"] = { mstack: [_34_] };\r\nconst _29_ = new MultiContextMachine(_ca_);\r\n_29_.initializeAndRun();\r\nconst _fa_ = _29_.context.mstack.at(0)!.context;\r\n// console.dir(_fa_, { depth:Infinity });\r\nconst deterministicDeployerAddress = _fa_.address!;\r\ntraceObjects.splice(0, traceObjects.length);\r\n\r\n// -- we think setting code in the context can be done in the initialization of a single context machine\r\n// deploy some code via the deterministic deployer\r\nconst _c6_ = createContext({\r\n    states,\r\n    origin: _63_.from,\r\n    sender: _63_.from,\r\n    to: deterministicDeployerAddress,\r\n    calldata: Uint8Array.fromHex(\"0\".repeat(64) + \"604260005260206000f3\").buffer,\r\n    gas: 100_000_000n,\r\n    value: 0n,\r\n    code: getStateValue(states, 0, \"accounts\", [deterministicDeployerAddress])!.code\r\n});\r\nconst _11_ = new SingleContextMachine(_c6_);\r\nconst _94_:InstanceType<typeof MultiContextMachine>[\"context\"] = { mstack: [_11_] };\r\nconst _76_ = new MultiContextMachine(_94_);\r\n_76_.initialize();\r\nwhile (_76_.continue()) {\r\n    _76_.step();\r\n    console.log(traceObjects.at(-1)); // logs each step of the deterministic deployment\r\n}\r\nconst _57_ = _76_.context.mstack.at(0)!.context;\r\nconsole.dir(_57_, { depth:Infinity });\r\n```","readmeFilename":"README.md","_rev":"1-bf7e504c0343ca4ea041b1e4904de02d"}