@feelyourprotocol/evm 8141.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +690 -0
- package/dist/cjs/binaryTreeAccessWitness.d.ts +61 -0
- package/dist/cjs/binaryTreeAccessWitness.d.ts.map +1 -0
- package/dist/cjs/binaryTreeAccessWitness.js +314 -0
- package/dist/cjs/binaryTreeAccessWitness.js.map +1 -0
- package/dist/cjs/chunkCache.d.ts +13 -0
- package/dist/cjs/chunkCache.d.ts.map +1 -0
- package/dist/cjs/chunkCache.js +30 -0
- package/dist/cjs/chunkCache.js.map +1 -0
- package/dist/cjs/constructors.d.ts +11 -0
- package/dist/cjs/constructors.d.ts.map +1 -0
- package/dist/cjs/constructors.js +30 -0
- package/dist/cjs/constructors.js.map +1 -0
- package/dist/cjs/eip7708.d.ts +24 -0
- package/dist/cjs/eip7708.d.ts.map +1 -0
- package/dist/cjs/eip7708.js +37 -0
- package/dist/cjs/eip7708.js.map +1 -0
- package/dist/cjs/eof/constants.d.ts +22 -0
- package/dist/cjs/eof/constants.d.ts.map +1 -0
- package/dist/cjs/eof/constants.js +31 -0
- package/dist/cjs/eof/constants.js.map +1 -0
- package/dist/cjs/eof/container.d.ts +87 -0
- package/dist/cjs/eof/container.d.ts.map +1 -0
- package/dist/cjs/eof/container.js +380 -0
- package/dist/cjs/eof/container.js.map +1 -0
- package/dist/cjs/eof/errors.d.ts +66 -0
- package/dist/cjs/eof/errors.d.ts.map +1 -0
- package/dist/cjs/eof/errors.js +200 -0
- package/dist/cjs/eof/errors.js.map +1 -0
- package/dist/cjs/eof/setup.d.ts +9 -0
- package/dist/cjs/eof/setup.d.ts.map +1 -0
- package/dist/cjs/eof/setup.js +26 -0
- package/dist/cjs/eof/setup.js.map +1 -0
- package/dist/cjs/eof/stackDelta.d.ts +10 -0
- package/dist/cjs/eof/stackDelta.d.ts.map +1 -0
- package/dist/cjs/eof/stackDelta.js +164 -0
- package/dist/cjs/eof/stackDelta.js.map +1 -0
- package/dist/cjs/eof/util.d.ts +8 -0
- package/dist/cjs/eof/util.d.ts.map +1 -0
- package/dist/cjs/eof/util.js +18 -0
- package/dist/cjs/eof/util.js.map +1 -0
- package/dist/cjs/eof/verify.d.ts +38 -0
- package/dist/cjs/eof/verify.d.ts.map +1 -0
- package/dist/cjs/eof/verify.js +436 -0
- package/dist/cjs/eof/verify.js.map +1 -0
- package/dist/cjs/errors.d.ts +40 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +43 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/evm.d.ts +181 -0
- package/dist/cjs/evm.d.ts.map +1 -0
- package/dist/cjs/evm.js +1142 -0
- package/dist/cjs/evm.js.map +1 -0
- package/dist/cjs/frameContext.d.ts +50 -0
- package/dist/cjs/frameContext.d.ts.map +1 -0
- package/dist/cjs/frameContext.js +17 -0
- package/dist/cjs/frameContext.js.map +1 -0
- package/dist/cjs/index.d.ts +18 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +43 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/interpreter.d.ts +361 -0
- package/dist/cjs/interpreter.d.ts.map +1 -0
- package/dist/cjs/interpreter.js +1057 -0
- package/dist/cjs/interpreter.js.map +1 -0
- package/dist/cjs/journal.d.ts +69 -0
- package/dist/cjs/journal.d.ts.map +1 -0
- package/dist/cjs/journal.js +247 -0
- package/dist/cjs/journal.js.map +1 -0
- package/dist/cjs/logger.d.ts +38 -0
- package/dist/cjs/logger.d.ts.map +1 -0
- package/dist/cjs/logger.js +126 -0
- package/dist/cjs/logger.js.map +1 -0
- package/dist/cjs/memory.d.ts +29 -0
- package/dist/cjs/memory.d.ts.map +1 -0
- package/dist/cjs/memory.js +75 -0
- package/dist/cjs/memory.js.map +1 -0
- package/dist/cjs/message.d.ts +70 -0
- package/dist/cjs/message.d.ts.map +1 -0
- package/dist/cjs/message.js +51 -0
- package/dist/cjs/message.js.map +1 -0
- package/dist/cjs/opcodes/EIP1283.d.ts +13 -0
- package/dist/cjs/opcodes/EIP1283.d.ts.map +1 -0
- package/dist/cjs/opcodes/EIP1283.js +58 -0
- package/dist/cjs/opcodes/EIP1283.js.map +1 -0
- package/dist/cjs/opcodes/EIP2200.d.ts +13 -0
- package/dist/cjs/opcodes/EIP2200.d.ts.map +1 -0
- package/dist/cjs/opcodes/EIP2200.js +64 -0
- package/dist/cjs/opcodes/EIP2200.js.map +1 -0
- package/dist/cjs/opcodes/EIP2929.d.ts +68 -0
- package/dist/cjs/opcodes/EIP2929.d.ts.map +1 -0
- package/dist/cjs/opcodes/EIP2929.js +146 -0
- package/dist/cjs/opcodes/EIP2929.js.map +1 -0
- package/dist/cjs/opcodes/codes.d.ts +45 -0
- package/dist/cjs/opcodes/codes.d.ts.map +1 -0
- package/dist/cjs/opcodes/codes.js +453 -0
- package/dist/cjs/opcodes/codes.js.map +1 -0
- package/dist/cjs/opcodes/functions.d.ts +11 -0
- package/dist/cjs/opcodes/functions.d.ts.map +1 -0
- package/dist/cjs/opcodes/functions.js +1778 -0
- package/dist/cjs/opcodes/functions.js.map +1 -0
- package/dist/cjs/opcodes/gas.d.ts +15 -0
- package/dist/cjs/opcodes/gas.d.ts.map +1 -0
- package/dist/cjs/opcodes/gas.js +1016 -0
- package/dist/cjs/opcodes/gas.js.map +1 -0
- package/dist/cjs/opcodes/index.d.ts +4 -0
- package/dist/cjs/opcodes/index.d.ts.map +1 -0
- package/dist/cjs/opcodes/index.js +20 -0
- package/dist/cjs/opcodes/index.js.map +1 -0
- package/dist/cjs/opcodes/util.d.ts +86 -0
- package/dist/cjs/opcodes/util.d.ts.map +1 -0
- package/dist/cjs/opcodes/util.js +281 -0
- package/dist/cjs/opcodes/util.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/params.d.ts +3 -0
- package/dist/cjs/params.d.ts.map +1 -0
- package/dist/cjs/params.js +424 -0
- package/dist/cjs/params.js.map +1 -0
- package/dist/cjs/precompiles/01-ecrecover.d.ts +4 -0
- package/dist/cjs/precompiles/01-ecrecover.d.ts.map +1 -0
- package/dist/cjs/precompiles/01-ecrecover.js +58 -0
- package/dist/cjs/precompiles/01-ecrecover.js.map +1 -0
- package/dist/cjs/precompiles/02-sha256.d.ts +4 -0
- package/dist/cjs/precompiles/02-sha256.d.ts.map +1 -0
- package/dist/cjs/precompiles/02-sha256.js +27 -0
- package/dist/cjs/precompiles/02-sha256.js.map +1 -0
- package/dist/cjs/precompiles/03-ripemd160.d.ts +4 -0
- package/dist/cjs/precompiles/03-ripemd160.d.ts.map +1 -0
- package/dist/cjs/precompiles/03-ripemd160.js +26 -0
- package/dist/cjs/precompiles/03-ripemd160.js.map +1 -0
- package/dist/cjs/precompiles/04-identity.d.ts +4 -0
- package/dist/cjs/precompiles/04-identity.d.ts.map +1 -0
- package/dist/cjs/precompiles/04-identity.js +24 -0
- package/dist/cjs/precompiles/04-identity.js.map +1 -0
- package/dist/cjs/precompiles/05-modexp.d.ts +5 -0
- package/dist/cjs/precompiles/05-modexp.d.ts.map +1 -0
- package/dist/cjs/precompiles/05-modexp.js +185 -0
- package/dist/cjs/precompiles/05-modexp.js.map +1 -0
- package/dist/cjs/precompiles/06-bn254-add.d.ts +4 -0
- package/dist/cjs/precompiles/06-bn254-add.d.ts.map +1 -0
- package/dist/cjs/precompiles/06-bn254-add.js +42 -0
- package/dist/cjs/precompiles/06-bn254-add.js.map +1 -0
- package/dist/cjs/precompiles/07-bn254-mul.d.ts +4 -0
- package/dist/cjs/precompiles/07-bn254-mul.d.ts.map +1 -0
- package/dist/cjs/precompiles/07-bn254-mul.js +43 -0
- package/dist/cjs/precompiles/07-bn254-mul.js.map +1 -0
- package/dist/cjs/precompiles/08-bn254-pairing.d.ts +4 -0
- package/dist/cjs/precompiles/08-bn254-pairing.d.ts.map +1 -0
- package/dist/cjs/precompiles/08-bn254-pairing.js +45 -0
- package/dist/cjs/precompiles/08-bn254-pairing.js.map +1 -0
- package/dist/cjs/precompiles/09-blake2f.d.ts +5 -0
- package/dist/cjs/precompiles/09-blake2f.d.ts.map +1 -0
- package/dist/cjs/precompiles/09-blake2f.js +201 -0
- package/dist/cjs/precompiles/09-blake2f.js.map +1 -0
- package/dist/cjs/precompiles/0a-kzg-point-evaluation.d.ts +5 -0
- package/dist/cjs/precompiles/0a-kzg-point-evaluation.d.ts.map +1 -0
- package/dist/cjs/precompiles/0a-kzg-point-evaluation.js +68 -0
- package/dist/cjs/precompiles/0a-kzg-point-evaluation.js.map +1 -0
- package/dist/cjs/precompiles/0b-bls12-g1add.d.ts +4 -0
- package/dist/cjs/precompiles/0b-bls12-g1add.d.ts.map +1 -0
- package/dist/cjs/precompiles/0b-bls12-g1add.js +49 -0
- package/dist/cjs/precompiles/0b-bls12-g1add.js.map +1 -0
- package/dist/cjs/precompiles/0c-bls12-g1msm.d.ts +4 -0
- package/dist/cjs/precompiles/0c-bls12-g1msm.d.ts.map +1 -0
- package/dist/cjs/precompiles/0c-bls12-g1msm.js +62 -0
- package/dist/cjs/precompiles/0c-bls12-g1msm.js.map +1 -0
- package/dist/cjs/precompiles/0d-bls12-g2add.d.ts +4 -0
- package/dist/cjs/precompiles/0d-bls12-g2add.d.ts.map +1 -0
- package/dist/cjs/precompiles/0d-bls12-g2add.js +51 -0
- package/dist/cjs/precompiles/0d-bls12-g2add.js.map +1 -0
- package/dist/cjs/precompiles/0e-bls12-g2msm.d.ts +4 -0
- package/dist/cjs/precompiles/0e-bls12-g2msm.d.ts.map +1 -0
- package/dist/cjs/precompiles/0e-bls12-g2msm.js +60 -0
- package/dist/cjs/precompiles/0e-bls12-g2msm.js.map +1 -0
- package/dist/cjs/precompiles/0f-bls12-pairing.d.ts +4 -0
- package/dist/cjs/precompiles/0f-bls12-pairing.d.ts.map +1 -0
- package/dist/cjs/precompiles/0f-bls12-pairing.js +66 -0
- package/dist/cjs/precompiles/0f-bls12-pairing.js.map +1 -0
- package/dist/cjs/precompiles/10-bls12-map-fp-to-g1.d.ts +4 -0
- package/dist/cjs/precompiles/10-bls12-map-fp-to-g1.d.ts.map +1 -0
- package/dist/cjs/precompiles/10-bls12-map-fp-to-g1.js +44 -0
- package/dist/cjs/precompiles/10-bls12-map-fp-to-g1.js.map +1 -0
- package/dist/cjs/precompiles/100-p256verify.d.ts +4 -0
- package/dist/cjs/precompiles/100-p256verify.d.ts.map +1 -0
- package/dist/cjs/precompiles/100-p256verify.js +131 -0
- package/dist/cjs/precompiles/100-p256verify.js.map +1 -0
- package/dist/cjs/precompiles/11-bls12-map-fp2-to-g2.d.ts +4 -0
- package/dist/cjs/precompiles/11-bls12-map-fp2-to-g2.d.ts.map +1 -0
- package/dist/cjs/precompiles/11-bls12-map-fp2-to-g2.js +47 -0
- package/dist/cjs/precompiles/11-bls12-map-fp2-to-g2.js.map +1 -0
- package/dist/cjs/precompiles/bls12_381/constants.d.ts +10 -0
- package/dist/cjs/precompiles/bls12_381/constants.d.ts.map +1 -0
- package/dist/cjs/precompiles/bls12_381/constants.js +274 -0
- package/dist/cjs/precompiles/bls12_381/constants.js.map +1 -0
- package/dist/cjs/precompiles/bls12_381/index.d.ts +5 -0
- package/dist/cjs/precompiles/bls12_381/index.d.ts.map +1 -0
- package/dist/cjs/precompiles/bls12_381/index.js +24 -0
- package/dist/cjs/precompiles/bls12_381/index.js.map +1 -0
- package/dist/cjs/precompiles/bls12_381/mcl.d.ts +45 -0
- package/dist/cjs/precompiles/bls12_381/mcl.d.ts.map +1 -0
- package/dist/cjs/precompiles/bls12_381/mcl.js +264 -0
- package/dist/cjs/precompiles/bls12_381/mcl.js.map +1 -0
- package/dist/cjs/precompiles/bls12_381/noble.d.ts +39 -0
- package/dist/cjs/precompiles/bls12_381/noble.d.ts.map +1 -0
- package/dist/cjs/precompiles/bls12_381/noble.js +228 -0
- package/dist/cjs/precompiles/bls12_381/noble.js.map +1 -0
- package/dist/cjs/precompiles/bls12_381/util.d.ts +35 -0
- package/dist/cjs/precompiles/bls12_381/util.d.ts.map +1 -0
- package/dist/cjs/precompiles/bls12_381/util.js +68 -0
- package/dist/cjs/precompiles/bls12_381/util.js.map +1 -0
- package/dist/cjs/precompiles/bn254/index.d.ts +3 -0
- package/dist/cjs/precompiles/bn254/index.d.ts.map +1 -0
- package/dist/cjs/precompiles/bn254/index.js +8 -0
- package/dist/cjs/precompiles/bn254/index.js.map +1 -0
- package/dist/cjs/precompiles/bn254/noble.d.ts +13 -0
- package/dist/cjs/precompiles/bn254/noble.d.ts.map +1 -0
- package/dist/cjs/precompiles/bn254/noble.js +124 -0
- package/dist/cjs/precompiles/bn254/noble.js.map +1 -0
- package/dist/cjs/precompiles/bn254/rustbn.d.ts +16 -0
- package/dist/cjs/precompiles/bn254/rustbn.d.ts.map +1 -0
- package/dist/cjs/precompiles/bn254/rustbn.js +33 -0
- package/dist/cjs/precompiles/bn254/rustbn.js.map +1 -0
- package/dist/cjs/precompiles/index.d.ts +67 -0
- package/dist/cjs/precompiles/index.d.ts.map +1 -0
- package/dist/cjs/precompiles/index.js +262 -0
- package/dist/cjs/precompiles/index.js.map +1 -0
- package/dist/cjs/precompiles/types.d.ts +13 -0
- package/dist/cjs/precompiles/types.d.ts.map +1 -0
- package/dist/cjs/precompiles/types.js +3 -0
- package/dist/cjs/precompiles/types.js.map +1 -0
- package/dist/cjs/precompiles/util.d.ts +30 -0
- package/dist/cjs/precompiles/util.d.ts.map +1 -0
- package/dist/cjs/precompiles/util.js +63 -0
- package/dist/cjs/precompiles/util.js.map +1 -0
- package/dist/cjs/stack.d.ts +55 -0
- package/dist/cjs/stack.d.ts.map +1 -0
- package/dist/cjs/stack.js +143 -0
- package/dist/cjs/stack.js.map +1 -0
- package/dist/cjs/stemCache.d.ts +20 -0
- package/dist/cjs/stemCache.d.ts.map +1 -0
- package/dist/cjs/stemCache.js +37 -0
- package/dist/cjs/stemCache.js.map +1 -0
- package/dist/cjs/transientStorage.d.ts +54 -0
- package/dist/cjs/transientStorage.d.ts.map +1 -0
- package/dist/cjs/transientStorage.js +113 -0
- package/dist/cjs/transientStorage.js.map +1 -0
- package/dist/cjs/types.d.ts +465 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +28 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/binaryTreeAccessWitness.d.ts +61 -0
- package/dist/esm/binaryTreeAccessWitness.d.ts.map +1 -0
- package/dist/esm/binaryTreeAccessWitness.js +308 -0
- package/dist/esm/binaryTreeAccessWitness.js.map +1 -0
- package/dist/esm/chunkCache.d.ts +13 -0
- package/dist/esm/chunkCache.d.ts.map +1 -0
- package/dist/esm/chunkCache.js +26 -0
- package/dist/esm/chunkCache.js.map +1 -0
- package/dist/esm/constructors.d.ts +11 -0
- package/dist/esm/constructors.d.ts.map +1 -0
- package/dist/esm/constructors.js +27 -0
- package/dist/esm/constructors.js.map +1 -0
- package/dist/esm/eip7708.d.ts +24 -0
- package/dist/esm/eip7708.d.ts.map +1 -0
- package/dist/esm/eip7708.js +32 -0
- package/dist/esm/eip7708.js.map +1 -0
- package/dist/esm/eof/constants.d.ts +22 -0
- package/dist/esm/eof/constants.d.ts.map +1 -0
- package/dist/esm/eof/constants.js +28 -0
- package/dist/esm/eof/constants.js.map +1 -0
- package/dist/esm/eof/container.d.ts +87 -0
- package/dist/esm/eof/container.d.ts.map +1 -0
- package/dist/esm/eof/container.js +375 -0
- package/dist/esm/eof/container.js.map +1 -0
- package/dist/esm/eof/errors.d.ts +66 -0
- package/dist/esm/eof/errors.d.ts.map +1 -0
- package/dist/esm/eof/errors.js +195 -0
- package/dist/esm/eof/errors.js.map +1 -0
- package/dist/esm/eof/setup.d.ts +9 -0
- package/dist/esm/eof/setup.d.ts.map +1 -0
- package/dist/esm/eof/setup.js +23 -0
- package/dist/esm/eof/setup.js.map +1 -0
- package/dist/esm/eof/stackDelta.d.ts +10 -0
- package/dist/esm/eof/stackDelta.d.ts.map +1 -0
- package/dist/esm/eof/stackDelta.js +161 -0
- package/dist/esm/eof/stackDelta.js.map +1 -0
- package/dist/esm/eof/util.d.ts +8 -0
- package/dist/esm/eof/util.d.ts.map +1 -0
- package/dist/esm/eof/util.js +14 -0
- package/dist/esm/eof/util.js.map +1 -0
- package/dist/esm/eof/verify.d.ts +38 -0
- package/dist/esm/eof/verify.d.ts.map +1 -0
- package/dist/esm/eof/verify.js +432 -0
- package/dist/esm/eof/verify.js.map +1 -0
- package/dist/esm/errors.d.ts +40 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +39 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/evm.d.ts +181 -0
- package/dist/esm/evm.d.ts.map +1 -0
- package/dist/esm/evm.js +1131 -0
- package/dist/esm/evm.js.map +1 -0
- package/dist/esm/frameContext.d.ts +50 -0
- package/dist/esm/frameContext.d.ts.map +1 -0
- package/dist/esm/frameContext.js +14 -0
- package/dist/esm/frameContext.js.map +1 -0
- package/dist/esm/index.d.ts +18 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/interpreter.d.ts +361 -0
- package/dist/esm/interpreter.d.ts.map +1 -0
- package/dist/esm/interpreter.js +1054 -0
- package/dist/esm/interpreter.js.map +1 -0
- package/dist/esm/journal.d.ts +69 -0
- package/dist/esm/journal.d.ts.map +1 -0
- package/dist/esm/journal.js +243 -0
- package/dist/esm/journal.js.map +1 -0
- package/dist/esm/logger.d.ts +38 -0
- package/dist/esm/logger.d.ts.map +1 -0
- package/dist/esm/logger.js +121 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/memory.d.ts +29 -0
- package/dist/esm/memory.d.ts.map +1 -0
- package/dist/esm/memory.js +71 -0
- package/dist/esm/memory.js.map +1 -0
- package/dist/esm/message.d.ts +70 -0
- package/dist/esm/message.d.ts.map +1 -0
- package/dist/esm/message.js +47 -0
- package/dist/esm/message.js.map +1 -0
- package/dist/esm/opcodes/EIP1283.d.ts +13 -0
- package/dist/esm/opcodes/EIP1283.d.ts.map +1 -0
- package/dist/esm/opcodes/EIP1283.js +55 -0
- package/dist/esm/opcodes/EIP1283.js.map +1 -0
- package/dist/esm/opcodes/EIP2200.d.ts +13 -0
- package/dist/esm/opcodes/EIP2200.d.ts.map +1 -0
- package/dist/esm/opcodes/EIP2200.js +61 -0
- package/dist/esm/opcodes/EIP2200.js.map +1 -0
- package/dist/esm/opcodes/EIP2929.d.ts +68 -0
- package/dist/esm/opcodes/EIP2929.d.ts.map +1 -0
- package/dist/esm/opcodes/EIP2929.js +138 -0
- package/dist/esm/opcodes/EIP2929.js.map +1 -0
- package/dist/esm/opcodes/codes.d.ts +45 -0
- package/dist/esm/opcodes/codes.d.ts.map +1 -0
- package/dist/esm/opcodes/codes.js +448 -0
- package/dist/esm/opcodes/codes.js.map +1 -0
- package/dist/esm/opcodes/functions.d.ts +11 -0
- package/dist/esm/opcodes/functions.d.ts.map +1 -0
- package/dist/esm/opcodes/functions.js +1775 -0
- package/dist/esm/opcodes/functions.js.map +1 -0
- package/dist/esm/opcodes/gas.d.ts +15 -0
- package/dist/esm/opcodes/gas.d.ts.map +1 -0
- package/dist/esm/opcodes/gas.js +1013 -0
- package/dist/esm/opcodes/gas.js.map +1 -0
- package/dist/esm/opcodes/index.d.ts +4 -0
- package/dist/esm/opcodes/index.d.ts.map +1 -0
- package/dist/esm/opcodes/index.js +4 -0
- package/dist/esm/opcodes/index.js.map +1 -0
- package/dist/esm/opcodes/util.d.ts +86 -0
- package/dist/esm/opcodes/util.d.ts.map +1 -0
- package/dist/esm/opcodes/util.js +257 -0
- package/dist/esm/opcodes/util.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/params.d.ts +3 -0
- package/dist/esm/params.d.ts.map +1 -0
- package/dist/esm/params.js +421 -0
- package/dist/esm/params.js.map +1 -0
- package/dist/esm/precompiles/01-ecrecover.d.ts +4 -0
- package/dist/esm/precompiles/01-ecrecover.d.ts.map +1 -0
- package/dist/esm/precompiles/01-ecrecover.js +55 -0
- package/dist/esm/precompiles/01-ecrecover.js.map +1 -0
- package/dist/esm/precompiles/02-sha256.d.ts +4 -0
- package/dist/esm/precompiles/02-sha256.d.ts.map +1 -0
- package/dist/esm/precompiles/02-sha256.js +24 -0
- package/dist/esm/precompiles/02-sha256.js.map +1 -0
- package/dist/esm/precompiles/03-ripemd160.d.ts +4 -0
- package/dist/esm/precompiles/03-ripemd160.d.ts.map +1 -0
- package/dist/esm/precompiles/03-ripemd160.js +23 -0
- package/dist/esm/precompiles/03-ripemd160.js.map +1 -0
- package/dist/esm/precompiles/04-identity.d.ts +4 -0
- package/dist/esm/precompiles/04-identity.d.ts.map +1 -0
- package/dist/esm/precompiles/04-identity.js +21 -0
- package/dist/esm/precompiles/04-identity.js.map +1 -0
- package/dist/esm/precompiles/05-modexp.d.ts +5 -0
- package/dist/esm/precompiles/05-modexp.d.ts.map +1 -0
- package/dist/esm/precompiles/05-modexp.js +181 -0
- package/dist/esm/precompiles/05-modexp.js.map +1 -0
- package/dist/esm/precompiles/06-bn254-add.d.ts +4 -0
- package/dist/esm/precompiles/06-bn254-add.d.ts.map +1 -0
- package/dist/esm/precompiles/06-bn254-add.js +39 -0
- package/dist/esm/precompiles/06-bn254-add.js.map +1 -0
- package/dist/esm/precompiles/07-bn254-mul.d.ts +4 -0
- package/dist/esm/precompiles/07-bn254-mul.d.ts.map +1 -0
- package/dist/esm/precompiles/07-bn254-mul.js +40 -0
- package/dist/esm/precompiles/07-bn254-mul.js.map +1 -0
- package/dist/esm/precompiles/08-bn254-pairing.d.ts +4 -0
- package/dist/esm/precompiles/08-bn254-pairing.d.ts.map +1 -0
- package/dist/esm/precompiles/08-bn254-pairing.js +42 -0
- package/dist/esm/precompiles/08-bn254-pairing.js.map +1 -0
- package/dist/esm/precompiles/09-blake2f.d.ts +5 -0
- package/dist/esm/precompiles/09-blake2f.d.ts.map +1 -0
- package/dist/esm/precompiles/09-blake2f.js +197 -0
- package/dist/esm/precompiles/09-blake2f.js.map +1 -0
- package/dist/esm/precompiles/0a-kzg-point-evaluation.d.ts +5 -0
- package/dist/esm/precompiles/0a-kzg-point-evaluation.d.ts.map +1 -0
- package/dist/esm/precompiles/0a-kzg-point-evaluation.js +64 -0
- package/dist/esm/precompiles/0a-kzg-point-evaluation.js.map +1 -0
- package/dist/esm/precompiles/0b-bls12-g1add.d.ts +4 -0
- package/dist/esm/precompiles/0b-bls12-g1add.d.ts.map +1 -0
- package/dist/esm/precompiles/0b-bls12-g1add.js +46 -0
- package/dist/esm/precompiles/0b-bls12-g1add.js.map +1 -0
- package/dist/esm/precompiles/0c-bls12-g1msm.d.ts +4 -0
- package/dist/esm/precompiles/0c-bls12-g1msm.d.ts.map +1 -0
- package/dist/esm/precompiles/0c-bls12-g1msm.js +59 -0
- package/dist/esm/precompiles/0c-bls12-g1msm.js.map +1 -0
- package/dist/esm/precompiles/0d-bls12-g2add.d.ts +4 -0
- package/dist/esm/precompiles/0d-bls12-g2add.d.ts.map +1 -0
- package/dist/esm/precompiles/0d-bls12-g2add.js +48 -0
- package/dist/esm/precompiles/0d-bls12-g2add.js.map +1 -0
- package/dist/esm/precompiles/0e-bls12-g2msm.d.ts +4 -0
- package/dist/esm/precompiles/0e-bls12-g2msm.d.ts.map +1 -0
- package/dist/esm/precompiles/0e-bls12-g2msm.js +57 -0
- package/dist/esm/precompiles/0e-bls12-g2msm.js.map +1 -0
- package/dist/esm/precompiles/0f-bls12-pairing.d.ts +4 -0
- package/dist/esm/precompiles/0f-bls12-pairing.d.ts.map +1 -0
- package/dist/esm/precompiles/0f-bls12-pairing.js +63 -0
- package/dist/esm/precompiles/0f-bls12-pairing.js.map +1 -0
- package/dist/esm/precompiles/10-bls12-map-fp-to-g1.d.ts +4 -0
- package/dist/esm/precompiles/10-bls12-map-fp-to-g1.d.ts.map +1 -0
- package/dist/esm/precompiles/10-bls12-map-fp-to-g1.js +41 -0
- package/dist/esm/precompiles/10-bls12-map-fp-to-g1.js.map +1 -0
- package/dist/esm/precompiles/100-p256verify.d.ts +4 -0
- package/dist/esm/precompiles/100-p256verify.d.ts.map +1 -0
- package/dist/esm/precompiles/100-p256verify.js +128 -0
- package/dist/esm/precompiles/100-p256verify.js.map +1 -0
- package/dist/esm/precompiles/11-bls12-map-fp2-to-g2.d.ts +4 -0
- package/dist/esm/precompiles/11-bls12-map-fp2-to-g2.d.ts.map +1 -0
- package/dist/esm/precompiles/11-bls12-map-fp2-to-g2.js +44 -0
- package/dist/esm/precompiles/11-bls12-map-fp2-to-g2.js.map +1 -0
- package/dist/esm/precompiles/bls12_381/constants.d.ts +10 -0
- package/dist/esm/precompiles/bls12_381/constants.d.ts.map +1 -0
- package/dist/esm/precompiles/bls12_381/constants.js +271 -0
- package/dist/esm/precompiles/bls12_381/constants.js.map +1 -0
- package/dist/esm/precompiles/bls12_381/index.d.ts +5 -0
- package/dist/esm/precompiles/bls12_381/index.d.ts.map +1 -0
- package/dist/esm/precompiles/bls12_381/index.js +5 -0
- package/dist/esm/precompiles/bls12_381/index.js.map +1 -0
- package/dist/esm/precompiles/bls12_381/mcl.d.ts +45 -0
- package/dist/esm/precompiles/bls12_381/mcl.d.ts.map +1 -0
- package/dist/esm/precompiles/bls12_381/mcl.js +254 -0
- package/dist/esm/precompiles/bls12_381/mcl.js.map +1 -0
- package/dist/esm/precompiles/bls12_381/noble.d.ts +39 -0
- package/dist/esm/precompiles/bls12_381/noble.d.ts.map +1 -0
- package/dist/esm/precompiles/bls12_381/noble.js +218 -0
- package/dist/esm/precompiles/bls12_381/noble.js.map +1 -0
- package/dist/esm/precompiles/bls12_381/util.d.ts +35 -0
- package/dist/esm/precompiles/bls12_381/util.d.ts.map +1 -0
- package/dist/esm/precompiles/bls12_381/util.js +63 -0
- package/dist/esm/precompiles/bls12_381/util.js.map +1 -0
- package/dist/esm/precompiles/bn254/index.d.ts +3 -0
- package/dist/esm/precompiles/bn254/index.d.ts.map +1 -0
- package/dist/esm/precompiles/bn254/index.js +3 -0
- package/dist/esm/precompiles/bn254/index.js.map +1 -0
- package/dist/esm/precompiles/bn254/noble.d.ts +13 -0
- package/dist/esm/precompiles/bn254/noble.d.ts.map +1 -0
- package/dist/esm/precompiles/bn254/noble.js +120 -0
- package/dist/esm/precompiles/bn254/noble.js.map +1 -0
- package/dist/esm/precompiles/bn254/rustbn.d.ts +16 -0
- package/dist/esm/precompiles/bn254/rustbn.d.ts.map +1 -0
- package/dist/esm/precompiles/bn254/rustbn.js +29 -0
- package/dist/esm/precompiles/bn254/rustbn.js.map +1 -0
- package/dist/esm/precompiles/index.d.ts +67 -0
- package/dist/esm/precompiles/index.d.ts.map +1 -0
- package/dist/esm/precompiles/index.js +251 -0
- package/dist/esm/precompiles/index.js.map +1 -0
- package/dist/esm/precompiles/types.d.ts +13 -0
- package/dist/esm/precompiles/types.d.ts.map +1 -0
- package/dist/esm/precompiles/types.js +2 -0
- package/dist/esm/precompiles/types.js.map +1 -0
- package/dist/esm/precompiles/util.d.ts +30 -0
- package/dist/esm/precompiles/util.d.ts.map +1 -0
- package/dist/esm/precompiles/util.js +57 -0
- package/dist/esm/precompiles/util.js.map +1 -0
- package/dist/esm/stack.d.ts +55 -0
- package/dist/esm/stack.d.ts.map +1 -0
- package/dist/esm/stack.js +139 -0
- package/dist/esm/stack.js.map +1 -0
- package/dist/esm/stemCache.d.ts +20 -0
- package/dist/esm/stemCache.d.ts.map +1 -0
- package/dist/esm/stemCache.js +33 -0
- package/dist/esm/stemCache.js.map +1 -0
- package/dist/esm/transientStorage.d.ts +54 -0
- package/dist/esm/transientStorage.d.ts.map +1 -0
- package/dist/esm/transientStorage.js +109 -0
- package/dist/esm/transientStorage.js.map +1 -0
- package/dist/esm/types.d.ts +465 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +23 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
- package/package.json +98 -0
- package/src/binaryTreeAccessWitness.ts +447 -0
- package/src/chunkCache.ts +36 -0
- package/src/constructors.ts +35 -0
- package/src/eip7708.ts +47 -0
- package/src/eof/constants.ts +36 -0
- package/src/eof/container.ts +495 -0
- package/src/eof/errors.ts +214 -0
- package/src/eof/setup.ts +27 -0
- package/src/eof/stackDelta.ts +169 -0
- package/src/eof/util.ts +16 -0
- package/src/eof/verify.ts +531 -0
- package/src/errors.ts +45 -0
- package/src/evm.ts +1415 -0
- package/src/frameContext.ts +56 -0
- package/src/index.ts +75 -0
- package/src/interpreter.ts +1437 -0
- package/src/journal.ts +317 -0
- package/src/logger.ts +180 -0
- package/src/memory.ts +82 -0
- package/src/message.ts +114 -0
- package/src/opcodes/EIP1283.ts +77 -0
- package/src/opcodes/EIP2200.ts +87 -0
- package/src/opcodes/EIP2929.ts +173 -0
- package/src/opcodes/codes.ts +528 -0
- package/src/opcodes/functions.ts +1937 -0
- package/src/opcodes/gas.ts +1329 -0
- package/src/opcodes/index.ts +3 -0
- package/src/opcodes/util.ts +313 -0
- package/src/params.ts +423 -0
- package/src/precompiles/01-ecrecover.ts +77 -0
- package/src/precompiles/02-sha256.ts +32 -0
- package/src/precompiles/03-ripemd160.ts +32 -0
- package/src/precompiles/04-identity.ts +29 -0
- package/src/precompiles/05-modexp.ts +215 -0
- package/src/precompiles/06-bn254-add.ts +49 -0
- package/src/precompiles/07-bn254-mul.ts +50 -0
- package/src/precompiles/08-bn254-pairing.ts +54 -0
- package/src/precompiles/09-blake2f.ts +243 -0
- package/src/precompiles/0a-kzg-point-evaluation.ts +94 -0
- package/src/precompiles/0b-bls12-g1add.ts +63 -0
- package/src/precompiles/0c-bls12-g1msm.ts +87 -0
- package/src/precompiles/0d-bls12-g2add.ts +66 -0
- package/src/precompiles/0e-bls12-g2msm.ts +84 -0
- package/src/precompiles/0f-bls12-pairing.ts +86 -0
- package/src/precompiles/10-bls12-map-fp-to-g1.ts +58 -0
- package/src/precompiles/100-p256verify.ts +152 -0
- package/src/precompiles/11-bls12-map-fp2-to-g2.ts +61 -0
- package/src/precompiles/bls12_381/constants.ts +278 -0
- package/src/precompiles/bls12_381/index.ts +4 -0
- package/src/precompiles/bls12_381/mcl.ts +376 -0
- package/src/precompiles/bls12_381/noble.ts +307 -0
- package/src/precompiles/bls12_381/util.ts +78 -0
- package/src/precompiles/bn254/index.ts +2 -0
- package/src/precompiles/bn254/noble.ts +156 -0
- package/src/precompiles/bn254/rustbn.ts +35 -0
- package/src/precompiles/index.ts +344 -0
- package/src/precompiles/types.ts +15 -0
- package/src/precompiles/util.ts +70 -0
- package/src/stack.ts +166 -0
- package/src/stemCache.ts +45 -0
- package/src/transientStorage.ts +131 -0
- package/src/types.ts +538 -0
package/src/evm.ts
ADDED
|
@@ -0,0 +1,1415 @@
|
|
|
1
|
+
import { Hardfork } from '@feelyourprotocol/common'
|
|
2
|
+
import type { BlockLevelAccessList, PrefixedHexString } from '@feelyourprotocol/util'
|
|
3
|
+
import {
|
|
4
|
+
Account,
|
|
5
|
+
Address,
|
|
6
|
+
BIGINT_0,
|
|
7
|
+
BIGINT_1,
|
|
8
|
+
EthereumJSErrorWithoutCode,
|
|
9
|
+
KECCAK256_NULL,
|
|
10
|
+
KECCAK256_RLP,
|
|
11
|
+
MAX_INTEGER,
|
|
12
|
+
bigIntToBytes,
|
|
13
|
+
bytesToUnprefixedHex,
|
|
14
|
+
createBlockLevelAccessList,
|
|
15
|
+
createZeroAddress,
|
|
16
|
+
equalsBytes,
|
|
17
|
+
generateAddress,
|
|
18
|
+
generateAddress2,
|
|
19
|
+
isDebugEnabled,
|
|
20
|
+
short,
|
|
21
|
+
} from '@feelyourprotocol/util'
|
|
22
|
+
import debugDefault from 'debug'
|
|
23
|
+
import { EventEmitter } from 'eventemitter3'
|
|
24
|
+
|
|
25
|
+
import { createEIP7708TransferLog } from './eip7708.ts'
|
|
26
|
+
import { FORMAT } from './eof/constants.ts'
|
|
27
|
+
import { isEOF } from './eof/util.ts'
|
|
28
|
+
import { EVMError } from './errors.ts'
|
|
29
|
+
import type { FrameExecutionContext } from './frameContext.ts'
|
|
30
|
+
import { Interpreter } from './interpreter.ts'
|
|
31
|
+
import { Journal } from './journal.ts'
|
|
32
|
+
import { EVMPerformanceLogger } from './logger.ts'
|
|
33
|
+
import { Message } from './message.ts'
|
|
34
|
+
import { getOpcodesForHF } from './opcodes/index.ts'
|
|
35
|
+
import { paramsEVM } from './params.ts'
|
|
36
|
+
import { NobleBLS, getActivePrecompiles, getPrecompileName } from './precompiles/index.ts'
|
|
37
|
+
import { TransientStorage } from './transientStorage.ts'
|
|
38
|
+
import {
|
|
39
|
+
type Block,
|
|
40
|
+
type CustomOpcode,
|
|
41
|
+
DELEGATION_7702_FLAG,
|
|
42
|
+
type EVMBLSInterface,
|
|
43
|
+
type EVMBN254Interface,
|
|
44
|
+
type EVMEvent,
|
|
45
|
+
type EVMInterface,
|
|
46
|
+
type EVMMockBlockchainInterface,
|
|
47
|
+
type EVMOpts,
|
|
48
|
+
type EVMResult,
|
|
49
|
+
type EVMRunCallOpts,
|
|
50
|
+
type EVMRunCodeOpts,
|
|
51
|
+
type ExecResult,
|
|
52
|
+
type Log,
|
|
53
|
+
} from './types.ts'
|
|
54
|
+
|
|
55
|
+
import type { Common, StateManagerInterface } from '@feelyourprotocol/common'
|
|
56
|
+
import type { BinaryTreeAccessWitness } from './binaryTreeAccessWitness.ts'
|
|
57
|
+
import type { InterpreterOpts } from './interpreter.ts'
|
|
58
|
+
import type { Timer } from './logger.ts'
|
|
59
|
+
import type { MessageWithTo } from './message.ts'
|
|
60
|
+
import type { AsyncDynamicGasHandler, SyncDynamicGasHandler } from './opcodes/gas.ts'
|
|
61
|
+
import type { OpHandler, OpcodeList, OpcodeMap } from './opcodes/index.ts'
|
|
62
|
+
import type { CustomPrecompile, PrecompileFunc } from './precompiles/index.ts'
|
|
63
|
+
|
|
64
|
+
const debug = debugDefault('evm:evm')
|
|
65
|
+
const debugGas = debugDefault('evm:gas')
|
|
66
|
+
const debugPrecompiles = debugDefault('evm:precompiles')
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a standardized ExecResult for out-of-gas errors.
|
|
70
|
+
* @param gasLimit - Gas limit consumed by the failing frame
|
|
71
|
+
* @returns Execution result describing the OOG failure
|
|
72
|
+
*/
|
|
73
|
+
export function OOGResult(gasLimit: bigint): ExecResult {
|
|
74
|
+
return {
|
|
75
|
+
returnValue: new Uint8Array(0),
|
|
76
|
+
executionGasUsed: gasLimit,
|
|
77
|
+
exceptionError: new EVMError(EVMError.errorMessages.OUT_OF_GAS),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Creates an ExecResult for code-deposit out-of-gas errors (EIP-3541).
|
|
82
|
+
* @param gasUsedCreateCode - Gas consumed while attempting to store code
|
|
83
|
+
*/
|
|
84
|
+
export function COOGResult(gasUsedCreateCode: bigint): ExecResult {
|
|
85
|
+
return {
|
|
86
|
+
returnValue: new Uint8Array(0),
|
|
87
|
+
executionGasUsed: gasUsedCreateCode,
|
|
88
|
+
exceptionError: new EVMError(EVMError.errorMessages.CODESTORE_OUT_OF_GAS),
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns an ExecResult signalling invalid bytecode input.
|
|
94
|
+
* @param gasLimit - Gas consumed up to the point of failure
|
|
95
|
+
*/
|
|
96
|
+
export function INVALID_BYTECODE_RESULT(gasLimit: bigint): ExecResult {
|
|
97
|
+
return {
|
|
98
|
+
returnValue: new Uint8Array(0),
|
|
99
|
+
executionGasUsed: gasLimit,
|
|
100
|
+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_BYTECODE_RESULT),
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Returns an ExecResult signalling invalid EOF formatting.
|
|
106
|
+
* @param gasLimit - Gas consumed up to the point of failure
|
|
107
|
+
*/
|
|
108
|
+
export function INVALID_EOF_RESULT(gasLimit: bigint): ExecResult {
|
|
109
|
+
return {
|
|
110
|
+
returnValue: new Uint8Array(0),
|
|
111
|
+
executionGasUsed: gasLimit,
|
|
112
|
+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT),
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns an ExecResult for code size violations.
|
|
118
|
+
* @param gasUsed - Gas consumed before the violation was detected
|
|
119
|
+
*/
|
|
120
|
+
export function CodesizeExceedsMaximumError(gasUsed: bigint): ExecResult {
|
|
121
|
+
return {
|
|
122
|
+
returnValue: new Uint8Array(0),
|
|
123
|
+
executionGasUsed: gasUsed,
|
|
124
|
+
exceptionError: new EVMError(EVMError.errorMessages.CODESIZE_EXCEEDS_MAXIMUM),
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Wraps an {@link EVMError} in an ExecResult.
|
|
130
|
+
* @param error - Error encountered during execution
|
|
131
|
+
* @param gasUsed - Gas consumed up to the error
|
|
132
|
+
*/
|
|
133
|
+
export function EVMErrorResult(error: EVMError, gasUsed: bigint): ExecResult {
|
|
134
|
+
return {
|
|
135
|
+
returnValue: new Uint8Array(0),
|
|
136
|
+
executionGasUsed: gasUsed,
|
|
137
|
+
exceptionError: error,
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Creates a default block header used by stand-alone executions.
|
|
143
|
+
* @returns Block-like object with zeroed header fields
|
|
144
|
+
*/
|
|
145
|
+
export function defaultBlock(): Block {
|
|
146
|
+
return {
|
|
147
|
+
header: {
|
|
148
|
+
number: BIGINT_0,
|
|
149
|
+
coinbase: createZeroAddress(),
|
|
150
|
+
timestamp: BIGINT_0,
|
|
151
|
+
difficulty: BIGINT_0,
|
|
152
|
+
prevRandao: new Uint8Array(32),
|
|
153
|
+
gasLimit: BIGINT_0,
|
|
154
|
+
baseFeePerGas: undefined,
|
|
155
|
+
getBlobGasPrice: () => undefined,
|
|
156
|
+
},
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The EVM (Ethereum Virtual Machine) is responsible for executing EVM bytecode, processing transactions, and managing state changes. It handles both contract calls and contract creation operations.
|
|
162
|
+
*
|
|
163
|
+
* An EVM instance can be created with the constructor method:
|
|
164
|
+
*
|
|
165
|
+
* - {@link createEVM}
|
|
166
|
+
*/
|
|
167
|
+
export class EVM implements EVMInterface {
|
|
168
|
+
protected static supportedHardforks = [
|
|
169
|
+
Hardfork.Chainstart,
|
|
170
|
+
Hardfork.Homestead,
|
|
171
|
+
Hardfork.Dao,
|
|
172
|
+
Hardfork.TangerineWhistle,
|
|
173
|
+
Hardfork.SpuriousDragon,
|
|
174
|
+
Hardfork.Byzantium,
|
|
175
|
+
Hardfork.Constantinople,
|
|
176
|
+
Hardfork.Petersburg,
|
|
177
|
+
Hardfork.Istanbul,
|
|
178
|
+
Hardfork.MuirGlacier,
|
|
179
|
+
Hardfork.Berlin,
|
|
180
|
+
Hardfork.London,
|
|
181
|
+
Hardfork.ArrowGlacier,
|
|
182
|
+
Hardfork.GrayGlacier,
|
|
183
|
+
Hardfork.MergeNetsplitBlock,
|
|
184
|
+
Hardfork.Paris,
|
|
185
|
+
Hardfork.Shanghai,
|
|
186
|
+
Hardfork.Cancun,
|
|
187
|
+
Hardfork.Prague,
|
|
188
|
+
Hardfork.Osaka,
|
|
189
|
+
Hardfork.Bpo1,
|
|
190
|
+
Hardfork.Bpo2,
|
|
191
|
+
Hardfork.Bpo3,
|
|
192
|
+
Hardfork.Bpo4,
|
|
193
|
+
Hardfork.Bpo5,
|
|
194
|
+
Hardfork.Amsterdam,
|
|
195
|
+
]
|
|
196
|
+
protected _tx?: {
|
|
197
|
+
gasPrice: bigint
|
|
198
|
+
origin: Address
|
|
199
|
+
}
|
|
200
|
+
protected _block?: Block
|
|
201
|
+
|
|
202
|
+
/** EIP-8141 frame execution context, set by the VM during frame tx execution */
|
|
203
|
+
public frameExecutionContext?: FrameExecutionContext
|
|
204
|
+
|
|
205
|
+
public readonly common: Common
|
|
206
|
+
public readonly events: EventEmitter<EVMEvent>
|
|
207
|
+
|
|
208
|
+
public stateManager: StateManagerInterface
|
|
209
|
+
public blockchain: EVMMockBlockchainInterface
|
|
210
|
+
public journal: Journal
|
|
211
|
+
public binaryAccessWitness?: BinaryTreeAccessWitness
|
|
212
|
+
public systemBinaryAccessWitness?: BinaryTreeAccessWitness
|
|
213
|
+
|
|
214
|
+
public readonly transientStorage: TransientStorage
|
|
215
|
+
|
|
216
|
+
protected _opcodes!: OpcodeList
|
|
217
|
+
|
|
218
|
+
public readonly allowUnlimitedContractSize: boolean
|
|
219
|
+
public readonly allowUnlimitedInitCodeSize: boolean
|
|
220
|
+
|
|
221
|
+
public readonly blockLevelAccessList?: BlockLevelAccessList
|
|
222
|
+
|
|
223
|
+
protected readonly _customOpcodes?: CustomOpcode[]
|
|
224
|
+
protected readonly _customPrecompiles?: CustomPrecompile[]
|
|
225
|
+
|
|
226
|
+
protected _handlers!: Map<number, OpHandler>
|
|
227
|
+
|
|
228
|
+
protected _dynamicGasHandlers!: Map<number, AsyncDynamicGasHandler | SyncDynamicGasHandler>
|
|
229
|
+
|
|
230
|
+
protected _opcodeMap!: OpcodeMap
|
|
231
|
+
|
|
232
|
+
protected _precompiles!: Map<string, PrecompileFunc>
|
|
233
|
+
|
|
234
|
+
protected readonly _optsCached: EVMOpts
|
|
235
|
+
|
|
236
|
+
protected performanceLogger: EVMPerformanceLogger
|
|
237
|
+
|
|
238
|
+
public get precompiles() {
|
|
239
|
+
return this._precompiles
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public get opcodes() {
|
|
243
|
+
return this._opcodes
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
protected readonly _bls?: EVMBLSInterface
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* EVM is run in DEBUG mode (default: false)
|
|
250
|
+
* Taken from DEBUG environment variable
|
|
251
|
+
*
|
|
252
|
+
* Safeguards on debug() calls are added for
|
|
253
|
+
* performance reasons to avoid string literal evaluation
|
|
254
|
+
* @hidden
|
|
255
|
+
*/
|
|
256
|
+
readonly DEBUG: boolean = false
|
|
257
|
+
|
|
258
|
+
protected readonly _emit: (topic: string, data: any) => Promise<void>
|
|
259
|
+
|
|
260
|
+
private _bn254: EVMBN254Interface
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
*
|
|
264
|
+
* Creates new EVM object
|
|
265
|
+
*
|
|
266
|
+
* @deprecated The direct usage of this constructor is replaced since
|
|
267
|
+
* non-finalized async initialization lead to side effects. Please
|
|
268
|
+
* use the async {@link createEVM} constructor instead (same API).
|
|
269
|
+
*
|
|
270
|
+
* @param opts The EVM options
|
|
271
|
+
* @param bn128 Initialized bn128 WASM object for precompile usage (internal)
|
|
272
|
+
*/
|
|
273
|
+
constructor(opts: EVMOpts) {
|
|
274
|
+
this.common = opts.common!
|
|
275
|
+
this.blockchain = opts.blockchain!
|
|
276
|
+
this.stateManager = opts.stateManager!
|
|
277
|
+
|
|
278
|
+
if (this.common.isActivatedEIP(7864)) {
|
|
279
|
+
const mandatory = ['checkChunkWitnessPresent']
|
|
280
|
+
for (const m of mandatory) {
|
|
281
|
+
if (!(m in this.stateManager)) {
|
|
282
|
+
throw EthereumJSErrorWithoutCode(
|
|
283
|
+
`State manager used must implement ${m} if Binary Trees (EIP-7864) is activated`,
|
|
284
|
+
)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
290
|
+
this.blockLevelAccessList = opts.blockLevelAccessList ?? createBlockLevelAccessList()
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
this.events = new EventEmitter<EVMEvent>()
|
|
294
|
+
this._optsCached = opts
|
|
295
|
+
|
|
296
|
+
// Supported EIPs
|
|
297
|
+
const supportedEIPs = [
|
|
298
|
+
1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3198, 3529, 3540, 3541, 3607, 3651, 3670,
|
|
299
|
+
3855, 3860, 4200, 4399, 4750, 4788, 4844, 4895, 5133, 5450, 5656, 6110, 6206, 6780, 7002,
|
|
300
|
+
7069, 7251, 7480, 7516, 7594, 7620, 7685, 7691, 7692, 7698, 7702, 7709, 7823, 7825, 7934,
|
|
301
|
+
7939, 7951, 8024, 8141,
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
for (const eip of this.common.eips()) {
|
|
305
|
+
if (!supportedEIPs.includes(eip)) {
|
|
306
|
+
throw EthereumJSErrorWithoutCode(`EIP-${eip} is not supported by the EVM`)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (!EVM.supportedHardforks.includes(this.common.hardfork() as Hardfork)) {
|
|
311
|
+
throw EthereumJSErrorWithoutCode(
|
|
312
|
+
`Hardfork ${this.common.hardfork()} not set as supported in supportedHardforks`,
|
|
313
|
+
)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this.common.updateParams(opts.params ?? paramsEVM)
|
|
317
|
+
|
|
318
|
+
this.allowUnlimitedContractSize = opts.allowUnlimitedContractSize ?? false
|
|
319
|
+
this.allowUnlimitedInitCodeSize = opts.allowUnlimitedInitCodeSize ?? false
|
|
320
|
+
this._customOpcodes = opts.customOpcodes
|
|
321
|
+
this._customPrecompiles = opts.customPrecompiles
|
|
322
|
+
|
|
323
|
+
this.journal = new Journal(this.stateManager, this.common)
|
|
324
|
+
this.transientStorage = new TransientStorage()
|
|
325
|
+
|
|
326
|
+
this.common.events.on('hardforkChanged', () => {
|
|
327
|
+
this.getActiveOpcodes()
|
|
328
|
+
this._precompiles = getActivePrecompiles(this.common, this._customPrecompiles)
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
// Initialize the opcode data
|
|
332
|
+
this.getActiveOpcodes()
|
|
333
|
+
this._precompiles = getActivePrecompiles(this.common, this._customPrecompiles)
|
|
334
|
+
|
|
335
|
+
// Precompile crypto libraries
|
|
336
|
+
if (this.common.isActivatedEIP(2537)) {
|
|
337
|
+
this._bls = opts.bls ?? new NobleBLS()
|
|
338
|
+
this._bls.init?.()
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
this._bn254 = opts.bn254!
|
|
342
|
+
|
|
343
|
+
this._emit = async (topic: string, data: any): Promise<void> => {
|
|
344
|
+
const listeners = this.events.listeners(topic as keyof EVMEvent)
|
|
345
|
+
for (const listener of listeners) {
|
|
346
|
+
if (listener.length === 2) {
|
|
347
|
+
await new Promise<void>((resolve) => {
|
|
348
|
+
listener(data, resolve)
|
|
349
|
+
})
|
|
350
|
+
} else {
|
|
351
|
+
listener(data)
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
this.performanceLogger = new EVMPerformanceLogger()
|
|
357
|
+
|
|
358
|
+
// Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables
|
|
359
|
+
this.DEBUG = isDebugEnabled('ethjs')
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Returns a list with the currently activated opcodes
|
|
364
|
+
* available for EVM execution
|
|
365
|
+
*/
|
|
366
|
+
getActiveOpcodes(): OpcodeList {
|
|
367
|
+
const data = getOpcodesForHF(this.common, this._customOpcodes)
|
|
368
|
+
this._opcodes = data.opcodes
|
|
369
|
+
this._dynamicGasHandlers = data.dynamicGasHandlers
|
|
370
|
+
this._handlers = data.handlers
|
|
371
|
+
this._opcodeMap = data.opcodeMap
|
|
372
|
+
return data.opcodes
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
protected async _executeCall(message: MessageWithTo): Promise<EVMResult> {
|
|
376
|
+
let gasLimit = message.gasLimit
|
|
377
|
+
const fromAddress = message.caller
|
|
378
|
+
|
|
379
|
+
if (this.common.isActivatedEIP(7864)) {
|
|
380
|
+
if (message.accessWitness === undefined) {
|
|
381
|
+
throw EthereumJSErrorWithoutCode('accessWitness is required for EIP-7864')
|
|
382
|
+
}
|
|
383
|
+
const sendsValue = message.value !== BIGINT_0
|
|
384
|
+
if (message.depth === 0) {
|
|
385
|
+
const originAccessGas = message.accessWitness.readAccountHeader(fromAddress)
|
|
386
|
+
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`)
|
|
387
|
+
|
|
388
|
+
let destAccessGas = message.accessWitness.readAccountCodeHash(message.to)
|
|
389
|
+
if (sendsValue) {
|
|
390
|
+
destAccessGas += message.accessWitness.writeAccountBasicData(message.to)
|
|
391
|
+
} else {
|
|
392
|
+
destAccessGas += message.accessWitness.readAccountBasicData(message.to)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
debugGas(`destAccessGas=${destAccessGas} waived off for target at depth=0`)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
let callAccessGas = message.accessWitness.readAccountBasicData(message.to)
|
|
399
|
+
if (sendsValue) {
|
|
400
|
+
callAccessGas += message.accessWitness.writeAccountBasicData(message.to)
|
|
401
|
+
}
|
|
402
|
+
gasLimit -= callAccessGas
|
|
403
|
+
if (gasLimit < BIGINT_0) {
|
|
404
|
+
if (this.DEBUG) {
|
|
405
|
+
debugGas(`callAccessGas charged(${callAccessGas}) caused OOG (-> ${gasLimit})`)
|
|
406
|
+
}
|
|
407
|
+
message.accessWitness.revert()
|
|
408
|
+
return { execResult: OOGResult(message.gasLimit) }
|
|
409
|
+
} else {
|
|
410
|
+
if (this.DEBUG) {
|
|
411
|
+
debugGas(`callAccessGas used (${callAccessGas} gas (-> ${gasLimit}))`)
|
|
412
|
+
}
|
|
413
|
+
message.accessWitness.commit()
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
let account = await this.stateManager.getAccount(fromAddress)
|
|
418
|
+
if (!account) {
|
|
419
|
+
account = new Account()
|
|
420
|
+
}
|
|
421
|
+
let errorMessage
|
|
422
|
+
// Reduce tx value from sender
|
|
423
|
+
if (!message.delegatecall) {
|
|
424
|
+
try {
|
|
425
|
+
await this._reduceSenderBalance(account, message)
|
|
426
|
+
} catch (e) {
|
|
427
|
+
errorMessage = e
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Load `to` account
|
|
432
|
+
let toAccount = await this.stateManager.getAccount(message.to)
|
|
433
|
+
if (!toAccount) {
|
|
434
|
+
if (this.common.isActivatedEIP(6800) || this.common.isActivatedEIP(7864)) {
|
|
435
|
+
const absenceProofAccessGas = message.accessWitness!.readAccountHeader(message.to)
|
|
436
|
+
gasLimit -= absenceProofAccessGas
|
|
437
|
+
if (gasLimit < BIGINT_0) {
|
|
438
|
+
if (this.DEBUG) {
|
|
439
|
+
debugGas(
|
|
440
|
+
`Proof of absence access charged(${absenceProofAccessGas}) caused OOG (-> ${gasLimit})`,
|
|
441
|
+
)
|
|
442
|
+
}
|
|
443
|
+
message.accessWitness?.revert()
|
|
444
|
+
return { execResult: OOGResult(message.gasLimit) }
|
|
445
|
+
} else {
|
|
446
|
+
if (this.DEBUG) {
|
|
447
|
+
debugGas(`Proof of absence access used (${absenceProofAccessGas} gas (-> ${gasLimit}))`)
|
|
448
|
+
}
|
|
449
|
+
message.accessWitness?.commit()
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
toAccount = new Account()
|
|
453
|
+
}
|
|
454
|
+
// Add tx value to the `to` account
|
|
455
|
+
if (!message.delegatecall) {
|
|
456
|
+
try {
|
|
457
|
+
await this._addToBalance(toAccount, message)
|
|
458
|
+
} catch (e: any) {
|
|
459
|
+
errorMessage = e
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// EIP-7928: Add codeAddress to BAL for DELEGATECALL/CALLCODE
|
|
464
|
+
// For these opcodes, `to` is the current contract but `codeAddress` is the target
|
|
465
|
+
// whose code is being executed. The target MUST be included in the BAL.
|
|
466
|
+
if (
|
|
467
|
+
this.common.isActivatedEIP(7928) &&
|
|
468
|
+
message.codeAddress !== undefined &&
|
|
469
|
+
message.codeAddress.toString() !== message.to.toString()
|
|
470
|
+
) {
|
|
471
|
+
this.blockLevelAccessList!.addAddress(message.codeAddress.toString())
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Load code
|
|
475
|
+
await this._loadCode(message)
|
|
476
|
+
let exit = false
|
|
477
|
+
if (!message.code || (typeof message.code !== 'function' && message.code.length === 0)) {
|
|
478
|
+
exit = true
|
|
479
|
+
if (this.DEBUG) {
|
|
480
|
+
debug(`Exit early on no code (CALL)`)
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (errorMessage !== undefined) {
|
|
484
|
+
exit = true
|
|
485
|
+
if (this.DEBUG) {
|
|
486
|
+
debug(`Exit early on value transfer overflowed (CALL)`)
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// EIP-7708: Create ETH transfer log for non-zero value transfers to a different account.
|
|
491
|
+
// CALLCODE always executes in the caller's context (to == caller), so it is a self-transfer.
|
|
492
|
+
// Self-transfers (caller == to) and DELEGATECALL do not emit a log.
|
|
493
|
+
let eip7708Log: Log | undefined
|
|
494
|
+
const isTransferToDifferentAccount = !equalsBytes(message.caller.bytes, message.to.bytes)
|
|
495
|
+
if (
|
|
496
|
+
this.common.isActivatedEIP(7708) &&
|
|
497
|
+
!message.delegatecall &&
|
|
498
|
+
message.value > BIGINT_0 &&
|
|
499
|
+
isTransferToDifferentAccount &&
|
|
500
|
+
errorMessage === undefined
|
|
501
|
+
) {
|
|
502
|
+
eip7708Log = createEIP7708TransferLog(message.caller, message.to, message.value)
|
|
503
|
+
if (this.DEBUG) {
|
|
504
|
+
debug(
|
|
505
|
+
`EIP-7708: Created ETH transfer log from ${message.caller} to ${message.to} value=${message.value}`,
|
|
506
|
+
)
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (exit) {
|
|
511
|
+
// Even on early exit, we may need to return the EIP-7708 log if value was transferred
|
|
512
|
+
return {
|
|
513
|
+
execResult: {
|
|
514
|
+
gasRefund: message.gasRefund,
|
|
515
|
+
executionGasUsed: message.gasLimit - gasLimit,
|
|
516
|
+
exceptionError: errorMessage, // Only defined if addToBalance failed
|
|
517
|
+
returnValue: new Uint8Array(0),
|
|
518
|
+
logs: eip7708Log ? [eip7708Log] : undefined,
|
|
519
|
+
},
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
let result: ExecResult
|
|
524
|
+
if (message.isCompiled) {
|
|
525
|
+
let timer: Timer
|
|
526
|
+
let callTimer: Timer | undefined
|
|
527
|
+
let target: string
|
|
528
|
+
if (this._optsCached.profiler?.enabled === true) {
|
|
529
|
+
// Using deprecated bytesToUnprefixedHex for performance: used for profiler string formatting.
|
|
530
|
+
target = bytesToUnprefixedHex(message.codeAddress.bytes)
|
|
531
|
+
// TODO: map target precompile not to address, but to a name
|
|
532
|
+
target = getPrecompileName(target) ?? target.slice(20)
|
|
533
|
+
if (this.performanceLogger.hasTimer()) {
|
|
534
|
+
callTimer = this.performanceLogger.pauseTimer()
|
|
535
|
+
}
|
|
536
|
+
timer = this.performanceLogger.startTimer(target)
|
|
537
|
+
}
|
|
538
|
+
result = await this.runPrecompile(message.code as PrecompileFunc, message.data, gasLimit)
|
|
539
|
+
|
|
540
|
+
if (eip7708Log !== undefined) {
|
|
541
|
+
result.logs = result.logs !== undefined ? [eip7708Log, ...result.logs] : [eip7708Log]
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (this._optsCached.profiler?.enabled === true) {
|
|
545
|
+
this.performanceLogger.stopTimer(timer!, Number(result.executionGasUsed), 'precompiles')
|
|
546
|
+
if (callTimer !== undefined) {
|
|
547
|
+
this.performanceLogger.unpauseTimer(callTimer)
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
result.gasRefund = message.gasRefund
|
|
551
|
+
} else {
|
|
552
|
+
if (this.DEBUG) {
|
|
553
|
+
debug(`Start bytecode processing...`)
|
|
554
|
+
}
|
|
555
|
+
result = await this.runInterpreter(
|
|
556
|
+
{
|
|
557
|
+
...{ codeAddress: message.codeAddress },
|
|
558
|
+
...message,
|
|
559
|
+
gasLimit,
|
|
560
|
+
} as Message,
|
|
561
|
+
{ initialLogs: eip7708Log ? [eip7708Log] : undefined },
|
|
562
|
+
)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (message.depth === 0) {
|
|
566
|
+
this.postMessageCleanup()
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
result.executionGasUsed += message.gasLimit - gasLimit
|
|
570
|
+
|
|
571
|
+
return {
|
|
572
|
+
execResult: result,
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
protected async _executeCreate(message: Message): Promise<EVMResult> {
|
|
577
|
+
let gasLimit = message.gasLimit
|
|
578
|
+
const fromAddress = message.caller
|
|
579
|
+
|
|
580
|
+
if (this.common.isActivatedEIP(6800) || this.common.isActivatedEIP(7864)) {
|
|
581
|
+
if (message.depth === 0) {
|
|
582
|
+
const originAccessGas = message.accessWitness!.readAccountHeader(fromAddress)
|
|
583
|
+
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`)
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
let account = await this.stateManager.getAccount(message.caller)
|
|
588
|
+
if (!account) {
|
|
589
|
+
account = new Account()
|
|
590
|
+
}
|
|
591
|
+
// Reduce tx value from sender
|
|
592
|
+
await this._reduceSenderBalance(account, message)
|
|
593
|
+
|
|
594
|
+
if (this.common.isActivatedEIP(3860)) {
|
|
595
|
+
if (
|
|
596
|
+
message.data.length > Number(this.common.param('maxInitCodeSize')) &&
|
|
597
|
+
!this.allowUnlimitedInitCodeSize
|
|
598
|
+
) {
|
|
599
|
+
return {
|
|
600
|
+
createdAddress: message.to,
|
|
601
|
+
execResult: {
|
|
602
|
+
returnValue: new Uint8Array(0),
|
|
603
|
+
exceptionError: new EVMError(EVMError.errorMessages.INITCODE_SIZE_VIOLATION),
|
|
604
|
+
executionGasUsed: message.gasLimit,
|
|
605
|
+
},
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// TODO at some point, figure out why we swapped out data to code in the first place
|
|
611
|
+
message.code = message.data
|
|
612
|
+
message.data = message.eofCallData ?? new Uint8Array()
|
|
613
|
+
message.to = await this._generateAddress(message)
|
|
614
|
+
|
|
615
|
+
if (this.common.isActivatedEIP(6780)) {
|
|
616
|
+
message.createdAddresses!.add(message.to.toString())
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if (this.DEBUG) {
|
|
620
|
+
debug(`Generated CREATE contract address ${message.to}`)
|
|
621
|
+
}
|
|
622
|
+
let toAccount = await this.stateManager.getAccount(message.to)
|
|
623
|
+
if (!toAccount) {
|
|
624
|
+
toAccount = new Account()
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (this.common.isActivatedEIP(6800) || this.common.isActivatedEIP(7864)) {
|
|
628
|
+
const contractCreateAccessGas =
|
|
629
|
+
message.accessWitness!.writeAccountBasicData(message.to) +
|
|
630
|
+
message.accessWitness!.readAccountCodeHash(message.to)
|
|
631
|
+
gasLimit -= contractCreateAccessGas
|
|
632
|
+
if (gasLimit < BIGINT_0) {
|
|
633
|
+
if (this.DEBUG) {
|
|
634
|
+
debugGas(
|
|
635
|
+
`ContractCreateInit charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`,
|
|
636
|
+
)
|
|
637
|
+
message.accessWitness?.revert()
|
|
638
|
+
}
|
|
639
|
+
return { execResult: OOGResult(message.gasLimit) }
|
|
640
|
+
} else {
|
|
641
|
+
if (this.DEBUG) {
|
|
642
|
+
debugGas(`ContractCreateInit charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`)
|
|
643
|
+
}
|
|
644
|
+
message.accessWitness?.commit()
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Check for collision
|
|
649
|
+
if (
|
|
650
|
+
(toAccount.nonce && toAccount.nonce > BIGINT_0) ||
|
|
651
|
+
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true) ||
|
|
652
|
+
// See EIP 7610 and the discussion `https://ethereum-magicians.org/t/eip-7610-revert-creation-in-case-of-non-empty-storage`
|
|
653
|
+
!(equalsBytes(toAccount.storageRoot, KECCAK256_RLP) === true)
|
|
654
|
+
) {
|
|
655
|
+
if (this.DEBUG) {
|
|
656
|
+
debug(`Returning on address collision`)
|
|
657
|
+
}
|
|
658
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
659
|
+
this.blockLevelAccessList!.addAddress(message.to.toString())
|
|
660
|
+
}
|
|
661
|
+
return {
|
|
662
|
+
createdAddress: message.to,
|
|
663
|
+
execResult: {
|
|
664
|
+
returnValue: new Uint8Array(0),
|
|
665
|
+
exceptionError: new EVMError(EVMError.errorMessages.CREATE_COLLISION),
|
|
666
|
+
executionGasUsed: message.gasLimit,
|
|
667
|
+
},
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
await this.journal.putAccount(message.to, toAccount)
|
|
672
|
+
await this.stateManager.clearStorage(message.to)
|
|
673
|
+
|
|
674
|
+
const newContractEvent = {
|
|
675
|
+
address: message.to,
|
|
676
|
+
code: message.code,
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
await this._emit('newContract', newContractEvent)
|
|
680
|
+
|
|
681
|
+
toAccount = await this.stateManager.getAccount(message.to)
|
|
682
|
+
if (!toAccount) {
|
|
683
|
+
toAccount = new Account()
|
|
684
|
+
}
|
|
685
|
+
// EIP-161 on account creation and CREATE execution
|
|
686
|
+
if (this.common.gteHardfork(Hardfork.SpuriousDragon)) {
|
|
687
|
+
toAccount.nonce += BIGINT_1
|
|
688
|
+
}
|
|
689
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
690
|
+
this.blockLevelAccessList!.addNonceChange(
|
|
691
|
+
message.to.toString(),
|
|
692
|
+
toAccount.nonce,
|
|
693
|
+
this.blockLevelAccessList!.blockAccessIndex,
|
|
694
|
+
)
|
|
695
|
+
}
|
|
696
|
+
// Add tx value to the `to` account
|
|
697
|
+
let errorMessage
|
|
698
|
+
try {
|
|
699
|
+
await this._addToBalance(toAccount, message as MessageWithTo)
|
|
700
|
+
} catch (e: any) {
|
|
701
|
+
errorMessage = e
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
let exit = false
|
|
705
|
+
if (
|
|
706
|
+
message.code === undefined ||
|
|
707
|
+
(typeof message.code !== 'function' && message.code.length === 0)
|
|
708
|
+
) {
|
|
709
|
+
exit = true
|
|
710
|
+
if (this.DEBUG) {
|
|
711
|
+
debug(`Exit early on no code (CREATE)`)
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (errorMessage !== undefined) {
|
|
715
|
+
exit = true
|
|
716
|
+
if (this.DEBUG) {
|
|
717
|
+
debug(`Exit early on value transfer overflowed (CREATE)`)
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// EIP-7708: Create ETH transfer log for contract creation with value
|
|
722
|
+
let eip7708CreateLog: Log | undefined
|
|
723
|
+
if (
|
|
724
|
+
this.common.isActivatedEIP(7708) &&
|
|
725
|
+
message.value > BIGINT_0 &&
|
|
726
|
+
message.to !== undefined &&
|
|
727
|
+
!equalsBytes(message.caller.bytes, message.to.bytes) &&
|
|
728
|
+
errorMessage === undefined
|
|
729
|
+
) {
|
|
730
|
+
eip7708CreateLog = createEIP7708TransferLog(message.caller, message.to, message.value)
|
|
731
|
+
if (this.DEBUG) {
|
|
732
|
+
debug(
|
|
733
|
+
`EIP-7708: Created ETH transfer log for CREATE from ${message.caller} to ${message.to} value=${message.value}`,
|
|
734
|
+
)
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (exit) {
|
|
739
|
+
if (this.common.isActivatedEIP(6800) || this.common.isActivatedEIP(7864)) {
|
|
740
|
+
const createCompleteAccessGas = message.accessWitness!.writeAccountHeader(message.to)
|
|
741
|
+
gasLimit -= createCompleteAccessGas
|
|
742
|
+
if (gasLimit < BIGINT_0) {
|
|
743
|
+
if (this.DEBUG) {
|
|
744
|
+
debug(
|
|
745
|
+
`ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`,
|
|
746
|
+
)
|
|
747
|
+
}
|
|
748
|
+
message.accessWitness?.revert()
|
|
749
|
+
return { execResult: OOGResult(message.gasLimit) }
|
|
750
|
+
} else {
|
|
751
|
+
if (this.DEBUG) {
|
|
752
|
+
debug(
|
|
753
|
+
`ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`,
|
|
754
|
+
)
|
|
755
|
+
}
|
|
756
|
+
message.accessWitness?.commit()
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
return {
|
|
761
|
+
createdAddress: message.to,
|
|
762
|
+
execResult: {
|
|
763
|
+
executionGasUsed: message.gasLimit - gasLimit,
|
|
764
|
+
gasRefund: message.gasRefund,
|
|
765
|
+
exceptionError: errorMessage, // only defined if addToBalance failed
|
|
766
|
+
returnValue: new Uint8Array(0),
|
|
767
|
+
logs: eip7708CreateLog ? [eip7708CreateLog] : undefined,
|
|
768
|
+
},
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (this.DEBUG) {
|
|
773
|
+
debug(`Start bytecode processing...`)
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// run the message with the updated gas limit and add accessed gas used to the result
|
|
777
|
+
let result = await this.runInterpreter({ ...message, gasLimit, isCreate: true } as Message, {
|
|
778
|
+
initialLogs: eip7708CreateLog ? [eip7708CreateLog] : undefined,
|
|
779
|
+
})
|
|
780
|
+
result.executionGasUsed += message.gasLimit - gasLimit
|
|
781
|
+
|
|
782
|
+
// fee for size of the return value
|
|
783
|
+
let totalGas = result.executionGasUsed
|
|
784
|
+
let returnFee = BIGINT_0
|
|
785
|
+
if (!result.exceptionError && !this.common.isActivatedEIP(6800)) {
|
|
786
|
+
returnFee = BigInt(result.returnValue.length) * BigInt(this.common.param('createDataGas'))
|
|
787
|
+
totalGas = totalGas + returnFee
|
|
788
|
+
if (this.DEBUG) {
|
|
789
|
+
debugGas(`Add return value size fee (${returnFee} to gas used (-> ${totalGas}))`)
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// Check for SpuriousDragon EIP-170 code size limit
|
|
794
|
+
let allowedCodeSize = true
|
|
795
|
+
if (
|
|
796
|
+
!result.exceptionError &&
|
|
797
|
+
this.common.gteHardfork(Hardfork.SpuriousDragon) &&
|
|
798
|
+
result.returnValue.length > Number(this.common.param('maxCodeSize'))
|
|
799
|
+
) {
|
|
800
|
+
allowedCodeSize = false
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// If enough gas and allowed code size
|
|
804
|
+
let CodestoreOOG = false
|
|
805
|
+
if (totalGas <= message.gasLimit && (this.allowUnlimitedContractSize || allowedCodeSize)) {
|
|
806
|
+
if (this.common.isActivatedEIP(3541) && result.returnValue[0] === FORMAT) {
|
|
807
|
+
if (!this.common.isActivatedEIP(3540)) {
|
|
808
|
+
result = { ...result, ...INVALID_BYTECODE_RESULT(message.gasLimit) }
|
|
809
|
+
} else if (
|
|
810
|
+
// TODO check if this is correct
|
|
811
|
+
// Also likely cleanup this eofCallData stuff
|
|
812
|
+
/*(message.depth > 0 && message.eofCallData === undefined) ||
|
|
813
|
+
(message.depth === 0 && !isEOF(message.code))*/
|
|
814
|
+
!isEOF(message.code)
|
|
815
|
+
) {
|
|
816
|
+
// TODO the message.eof was flagged for this to work for this first
|
|
817
|
+
// Running into Legacy mode: unable to deploy EOF contract
|
|
818
|
+
result = { ...result, ...INVALID_BYTECODE_RESULT(message.gasLimit) }
|
|
819
|
+
} else {
|
|
820
|
+
// 3541 is active and current runtime mode is EOF
|
|
821
|
+
result.executionGasUsed = totalGas
|
|
822
|
+
}
|
|
823
|
+
} else {
|
|
824
|
+
result.executionGasUsed = totalGas
|
|
825
|
+
}
|
|
826
|
+
} else {
|
|
827
|
+
if (this.common.gteHardfork(Hardfork.Homestead)) {
|
|
828
|
+
if (!allowedCodeSize) {
|
|
829
|
+
if (this.DEBUG) {
|
|
830
|
+
debug(`Code size exceeds maximum code size (>= SpuriousDragon)`)
|
|
831
|
+
}
|
|
832
|
+
result = { ...result, ...CodesizeExceedsMaximumError(message.gasLimit) }
|
|
833
|
+
} else {
|
|
834
|
+
if (this.DEBUG) {
|
|
835
|
+
debug(`Contract creation: out of gas`)
|
|
836
|
+
}
|
|
837
|
+
message.accessWitness?.revert()
|
|
838
|
+
result = { ...result, ...OOGResult(message.gasLimit) }
|
|
839
|
+
}
|
|
840
|
+
} else {
|
|
841
|
+
// we are in Frontier
|
|
842
|
+
if (totalGas - returnFee <= message.gasLimit) {
|
|
843
|
+
// we cannot pay the code deposit fee (but the deposit code actually did run)
|
|
844
|
+
if (this.DEBUG) {
|
|
845
|
+
debug(`Not enough gas to pay the code deposit fee (Frontier)`)
|
|
846
|
+
}
|
|
847
|
+
message.accessWitness?.revert()
|
|
848
|
+
result = { ...result, ...COOGResult(totalGas - returnFee) }
|
|
849
|
+
CodestoreOOG = true
|
|
850
|
+
} else {
|
|
851
|
+
if (this.DEBUG) {
|
|
852
|
+
debug(`Contract creation: out of gas`)
|
|
853
|
+
}
|
|
854
|
+
message.accessWitness?.revert()
|
|
855
|
+
result = { ...result, ...OOGResult(message.gasLimit) }
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// get the fresh gas limit for the rest of the ops
|
|
861
|
+
gasLimit = message.gasLimit - result.executionGasUsed
|
|
862
|
+
if (
|
|
863
|
+
!result.exceptionError &&
|
|
864
|
+
(this.common.isActivatedEIP(6800) || this.common.isActivatedEIP(7864))
|
|
865
|
+
) {
|
|
866
|
+
const createCompleteAccessGas = message.accessWitness!.writeAccountHeader(message.to)
|
|
867
|
+
gasLimit -= createCompleteAccessGas
|
|
868
|
+
if (gasLimit < BIGINT_0) {
|
|
869
|
+
if (this.DEBUG) {
|
|
870
|
+
debug(
|
|
871
|
+
`ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`,
|
|
872
|
+
)
|
|
873
|
+
}
|
|
874
|
+
message.accessWitness?.revert()
|
|
875
|
+
result = { ...result, ...OOGResult(message.gasLimit) }
|
|
876
|
+
} else {
|
|
877
|
+
debug(
|
|
878
|
+
`ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`,
|
|
879
|
+
)
|
|
880
|
+
result.executionGasUsed += createCompleteAccessGas
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Save code if a new contract was created
|
|
885
|
+
if (
|
|
886
|
+
!result.exceptionError &&
|
|
887
|
+
result.returnValue !== undefined &&
|
|
888
|
+
result.returnValue.length !== 0
|
|
889
|
+
) {
|
|
890
|
+
// Add access charges for writing this code to the state
|
|
891
|
+
if (this.common.isActivatedEIP(6800) || this.common.isActivatedEIP(7864)) {
|
|
892
|
+
const byteCodeWriteAccessfee = message.accessWitness!.writeAccountCodeChunks(
|
|
893
|
+
message.to,
|
|
894
|
+
0,
|
|
895
|
+
result.returnValue.length - 1,
|
|
896
|
+
)
|
|
897
|
+
gasLimit -= byteCodeWriteAccessfee
|
|
898
|
+
if (gasLimit < BIGINT_0) {
|
|
899
|
+
if (this.DEBUG) {
|
|
900
|
+
debug(
|
|
901
|
+
`byteCodeWrite access gas (${byteCodeWriteAccessfee}) caused OOG (-> ${gasLimit})`,
|
|
902
|
+
)
|
|
903
|
+
}
|
|
904
|
+
message.accessWitness?.revert()
|
|
905
|
+
result = { ...result, ...OOGResult(message.gasLimit) }
|
|
906
|
+
} else {
|
|
907
|
+
debug(`byteCodeWrite access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`)
|
|
908
|
+
message.accessWitness?.commit()
|
|
909
|
+
result.executionGasUsed += byteCodeWriteAccessfee
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
await this.stateManager.putCode(message.to, result.returnValue)
|
|
914
|
+
|
|
915
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
916
|
+
this.blockLevelAccessList!.addCodeChange(
|
|
917
|
+
message.to.toString(),
|
|
918
|
+
result.returnValue,
|
|
919
|
+
this.blockLevelAccessList!.blockAccessIndex,
|
|
920
|
+
)
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
if (this.DEBUG) {
|
|
924
|
+
debug(`Code saved on new contract creation`)
|
|
925
|
+
}
|
|
926
|
+
} else if (CodestoreOOG) {
|
|
927
|
+
// This only happens at Frontier. But, let's do a sanity check;
|
|
928
|
+
if (!this.common.gteHardfork(Hardfork.Homestead)) {
|
|
929
|
+
// Pre-Homestead behavior; put an empty contract.
|
|
930
|
+
// This contract would be considered "DEAD" in later hard forks.
|
|
931
|
+
// It is thus an unnecessary default item, which we have to save to disk
|
|
932
|
+
// It does change the state root, but it only wastes storage.
|
|
933
|
+
const account = await this.stateManager.getAccount(message.to)
|
|
934
|
+
await this.journal.putAccount(message.to, account ?? new Account())
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
if (message.depth === 0) {
|
|
939
|
+
this.postMessageCleanup()
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
return {
|
|
943
|
+
createdAddress: message.to,
|
|
944
|
+
execResult: result,
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Starts the actual bytecode processing for a CALL or CREATE
|
|
950
|
+
*/
|
|
951
|
+
protected async runInterpreter(
|
|
952
|
+
message: Message,
|
|
953
|
+
opts: InterpreterOpts = {},
|
|
954
|
+
): Promise<ExecResult> {
|
|
955
|
+
let contract = await this.stateManager.getAccount(message.to ?? createZeroAddress())
|
|
956
|
+
if (!contract) {
|
|
957
|
+
contract = new Account()
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
const env = {
|
|
961
|
+
address: message.to ?? createZeroAddress(),
|
|
962
|
+
caller: message.caller ?? createZeroAddress(),
|
|
963
|
+
callData: message.data ?? Uint8Array.from([0]),
|
|
964
|
+
callValue: message.value ?? BIGINT_0,
|
|
965
|
+
code: message.code as Uint8Array,
|
|
966
|
+
isStatic: message.isStatic ?? false,
|
|
967
|
+
isCreate: message.isCreate ?? false,
|
|
968
|
+
depth: message.depth ?? 0,
|
|
969
|
+
gasPrice: this._tx!.gasPrice,
|
|
970
|
+
origin: this._tx!.origin ?? message.caller ?? createZeroAddress(),
|
|
971
|
+
block: this._block ?? defaultBlock(),
|
|
972
|
+
contract,
|
|
973
|
+
codeAddress: message.codeAddress,
|
|
974
|
+
gasRefund: message.gasRefund,
|
|
975
|
+
chargeCodeAccesses: message.chargeCodeAccesses,
|
|
976
|
+
blobVersionedHashes: message.blobVersionedHashes ?? [],
|
|
977
|
+
accessWitness: message.accessWitness,
|
|
978
|
+
createdAddresses: message.createdAddresses,
|
|
979
|
+
initialLogs: opts.initialLogs,
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
const interpreter = new Interpreter(
|
|
983
|
+
this,
|
|
984
|
+
this.stateManager,
|
|
985
|
+
this.blockchain,
|
|
986
|
+
env,
|
|
987
|
+
message.gasLimit,
|
|
988
|
+
this.journal,
|
|
989
|
+
this.performanceLogger,
|
|
990
|
+
this._optsCached.profiler,
|
|
991
|
+
)
|
|
992
|
+
if (message.selfdestruct) {
|
|
993
|
+
interpreter._result.selfdestruct = message.selfdestruct
|
|
994
|
+
}
|
|
995
|
+
if (message.createdAddresses) {
|
|
996
|
+
interpreter._result.createdAddresses = message.createdAddresses
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
const interpreterRes = await interpreter.run(message.code as Uint8Array, opts)
|
|
1000
|
+
|
|
1001
|
+
let result = interpreter._result
|
|
1002
|
+
let gasUsed = message.gasLimit - interpreterRes.runState!.gasLeft
|
|
1003
|
+
if (interpreterRes.exceptionError) {
|
|
1004
|
+
if (
|
|
1005
|
+
interpreterRes.exceptionError.error !== EVMError.errorMessages.REVERT &&
|
|
1006
|
+
interpreterRes.exceptionError.error !== EVMError.errorMessages.INVALID_EOF_FORMAT
|
|
1007
|
+
) {
|
|
1008
|
+
gasUsed = message.gasLimit
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// Clear the result on error
|
|
1012
|
+
result = {
|
|
1013
|
+
...result,
|
|
1014
|
+
logs: [],
|
|
1015
|
+
selfdestruct: new Map(),
|
|
1016
|
+
createdAddresses: new Set(),
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
message.accessWitness?.commit()
|
|
1021
|
+
return {
|
|
1022
|
+
...result,
|
|
1023
|
+
runState: {
|
|
1024
|
+
...interpreterRes.runState!,
|
|
1025
|
+
...result,
|
|
1026
|
+
...interpreter._env,
|
|
1027
|
+
},
|
|
1028
|
+
exceptionError: interpreterRes.exceptionError,
|
|
1029
|
+
gas: interpreterRes.runState?.gasLeft,
|
|
1030
|
+
executionGasUsed: gasUsed,
|
|
1031
|
+
gasRefund: interpreterRes.runState!.gasRefund,
|
|
1032
|
+
returnValue: result.returnValue ?? new Uint8Array(0),
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* Executes an EVM message, determining whether it's a call or create
|
|
1038
|
+
* based on the `to` address. It checkpoints the state and reverts changes
|
|
1039
|
+
* if an exception happens during the message execution.
|
|
1040
|
+
*/
|
|
1041
|
+
async runCall(opts: EVMRunCallOpts): Promise<EVMResult> {
|
|
1042
|
+
let timer: Timer | undefined
|
|
1043
|
+
if (
|
|
1044
|
+
(opts.depth === 0 || opts.message === undefined) &&
|
|
1045
|
+
this._optsCached.profiler?.enabled === true
|
|
1046
|
+
) {
|
|
1047
|
+
timer = this.performanceLogger.startTimer('Initialization')
|
|
1048
|
+
}
|
|
1049
|
+
let message = opts.message
|
|
1050
|
+
let callerAccount
|
|
1051
|
+
if (!message) {
|
|
1052
|
+
this._block = opts.block ?? defaultBlock()
|
|
1053
|
+
const caller = opts.caller ?? createZeroAddress()
|
|
1054
|
+
this._tx = {
|
|
1055
|
+
gasPrice: opts.gasPrice ?? BIGINT_0,
|
|
1056
|
+
origin: opts.origin ?? caller,
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
const value = opts.value ?? BIGINT_0
|
|
1060
|
+
if (opts.skipBalance === true) {
|
|
1061
|
+
callerAccount = await this.stateManager.getAccount(caller)
|
|
1062
|
+
if (!callerAccount) {
|
|
1063
|
+
callerAccount = new Account()
|
|
1064
|
+
}
|
|
1065
|
+
const originalBalance = callerAccount.balance
|
|
1066
|
+
if (callerAccount.balance < value) {
|
|
1067
|
+
// if skipBalance and balance less than value, set caller balance to `value` to ensure sufficient funds
|
|
1068
|
+
callerAccount.balance = value
|
|
1069
|
+
await this.journal.putAccount(caller, callerAccount)
|
|
1070
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1071
|
+
this.blockLevelAccessList!.addBalanceChange(
|
|
1072
|
+
caller.toString(),
|
|
1073
|
+
callerAccount.balance,
|
|
1074
|
+
this.blockLevelAccessList!.blockAccessIndex,
|
|
1075
|
+
originalBalance,
|
|
1076
|
+
)
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
message = new Message({
|
|
1082
|
+
caller,
|
|
1083
|
+
gasLimit: opts.gasLimit ?? BigInt(0xffffff),
|
|
1084
|
+
to: opts.to,
|
|
1085
|
+
value,
|
|
1086
|
+
data: opts.data,
|
|
1087
|
+
code: opts.code,
|
|
1088
|
+
depth: opts.depth,
|
|
1089
|
+
isCompiled: opts.isCompiled,
|
|
1090
|
+
isStatic: opts.isStatic,
|
|
1091
|
+
salt: opts.salt,
|
|
1092
|
+
selfdestruct: opts.selfdestruct ?? new Map(),
|
|
1093
|
+
createdAddresses: opts.createdAddresses ?? new Set(),
|
|
1094
|
+
delegatecall: opts.delegatecall,
|
|
1095
|
+
blobVersionedHashes: opts.blobVersionedHashes,
|
|
1096
|
+
})
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
if (message.depth === 0) {
|
|
1100
|
+
if (!callerAccount) {
|
|
1101
|
+
callerAccount = await this.stateManager.getAccount(message.caller)
|
|
1102
|
+
}
|
|
1103
|
+
if (!callerAccount) {
|
|
1104
|
+
callerAccount = new Account()
|
|
1105
|
+
}
|
|
1106
|
+
callerAccount.nonce++
|
|
1107
|
+
await this.journal.putAccount(message.caller, callerAccount)
|
|
1108
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1109
|
+
this.blockLevelAccessList!.addNonceChange(
|
|
1110
|
+
message.caller.toString(),
|
|
1111
|
+
callerAccount.nonce,
|
|
1112
|
+
this.blockLevelAccessList!.blockAccessIndex,
|
|
1113
|
+
)
|
|
1114
|
+
}
|
|
1115
|
+
if (this.DEBUG) {
|
|
1116
|
+
debug(`Update fromAccount (caller) nonce (-> ${callerAccount.nonce}))`)
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
await this._emit('beforeMessage', message)
|
|
1121
|
+
|
|
1122
|
+
if (!message.to && this.common.isActivatedEIP(2929)) {
|
|
1123
|
+
message.code = message.data
|
|
1124
|
+
this.journal.addWarmedAddress((await this._generateAddress(message)).bytes)
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1128
|
+
this.blockLevelAccessList?.checkpoint()
|
|
1129
|
+
}
|
|
1130
|
+
await this.journal.checkpoint()
|
|
1131
|
+
if (this.common.isActivatedEIP(1153)) this.transientStorage.checkpoint()
|
|
1132
|
+
if (this.DEBUG) {
|
|
1133
|
+
debug('-'.repeat(100))
|
|
1134
|
+
debug(`message checkpoint`)
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
let result
|
|
1138
|
+
if (this.DEBUG) {
|
|
1139
|
+
const { caller, gasLimit, to, value, delegatecall } = message
|
|
1140
|
+
debug(
|
|
1141
|
+
`New message caller=${caller} gasLimit=${gasLimit} to=${
|
|
1142
|
+
to?.toString() ?? 'none'
|
|
1143
|
+
} value=${value} delegatecall=${delegatecall ? 'yes' : 'no'}`,
|
|
1144
|
+
)
|
|
1145
|
+
}
|
|
1146
|
+
if (message.to) {
|
|
1147
|
+
if (this.DEBUG) {
|
|
1148
|
+
debug(`Message CALL execution (to: ${message.to})`)
|
|
1149
|
+
}
|
|
1150
|
+
result = await this._executeCall(message as MessageWithTo)
|
|
1151
|
+
} else {
|
|
1152
|
+
if (this.DEBUG) {
|
|
1153
|
+
debug(`Message CREATE execution (to: undefined)`)
|
|
1154
|
+
}
|
|
1155
|
+
result = await this._executeCreate(message)
|
|
1156
|
+
}
|
|
1157
|
+
if (this.DEBUG) {
|
|
1158
|
+
const { executionGasUsed, exceptionError, returnValue } = result.execResult
|
|
1159
|
+
debug(
|
|
1160
|
+
`Received message execResult: [ gasUsed=${executionGasUsed} exceptionError=${
|
|
1161
|
+
exceptionError ? `'${exceptionError.error}'` : 'none'
|
|
1162
|
+
} returnValue=${short(returnValue)} gasRefund=${result.execResult.gasRefund ?? 0} ]`,
|
|
1163
|
+
)
|
|
1164
|
+
}
|
|
1165
|
+
const err = result.execResult.exceptionError
|
|
1166
|
+
// This clause captures any error which happened during execution
|
|
1167
|
+
// If that is the case, then all refunds are forfeited
|
|
1168
|
+
// There is one exception: if the CODESTORE_OUT_OF_GAS error is thrown
|
|
1169
|
+
// (this only happens the Frontier/Chainstart fork)
|
|
1170
|
+
// then the error is dismissed
|
|
1171
|
+
if (err && err.error !== EVMError.errorMessages.CODESTORE_OUT_OF_GAS) {
|
|
1172
|
+
result.execResult.selfdestruct = new Map()
|
|
1173
|
+
result.execResult.createdAddresses = new Set()
|
|
1174
|
+
result.execResult.gasRefund = BIGINT_0
|
|
1175
|
+
}
|
|
1176
|
+
if (
|
|
1177
|
+
err &&
|
|
1178
|
+
!(
|
|
1179
|
+
this.common.hardfork() === Hardfork.Chainstart &&
|
|
1180
|
+
err.error === EVMError.errorMessages.CODESTORE_OUT_OF_GAS
|
|
1181
|
+
)
|
|
1182
|
+
) {
|
|
1183
|
+
result.execResult.logs = []
|
|
1184
|
+
await this.journal.revert()
|
|
1185
|
+
if (this.common.isActivatedEIP(1153)) this.transientStorage.revert()
|
|
1186
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1187
|
+
this.blockLevelAccessList?.revert()
|
|
1188
|
+
}
|
|
1189
|
+
if (this.DEBUG) {
|
|
1190
|
+
debug(`message checkpoint reverted`)
|
|
1191
|
+
}
|
|
1192
|
+
} else {
|
|
1193
|
+
await this.journal.commit()
|
|
1194
|
+
if (this.common.isActivatedEIP(1153)) this.transientStorage.commit()
|
|
1195
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1196
|
+
this.blockLevelAccessList?.commit()
|
|
1197
|
+
}
|
|
1198
|
+
if (this.DEBUG) {
|
|
1199
|
+
debug(`message checkpoint committed`)
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
await this._emit('afterMessage', result)
|
|
1203
|
+
|
|
1204
|
+
if (message.depth === 0 && this._optsCached.profiler?.enabled === true) {
|
|
1205
|
+
this.performanceLogger.stopTimer(timer!, 0)
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
message.accessWitness?.commit()
|
|
1209
|
+
return result
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* Bound to the global VM and therefore
|
|
1214
|
+
* shouldn't be used directly from the evm class
|
|
1215
|
+
*/
|
|
1216
|
+
async runCode(opts: EVMRunCodeOpts): Promise<ExecResult> {
|
|
1217
|
+
this._block = opts.block ?? defaultBlock()
|
|
1218
|
+
|
|
1219
|
+
this._tx = {
|
|
1220
|
+
gasPrice: opts.gasPrice ?? BIGINT_0,
|
|
1221
|
+
origin: opts.origin ?? opts.caller ?? createZeroAddress(),
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
const message = new Message({
|
|
1225
|
+
code: opts.code,
|
|
1226
|
+
data: opts.data,
|
|
1227
|
+
gasLimit: opts.gasLimit ?? BigInt(0xffffff),
|
|
1228
|
+
to: opts.to ?? createZeroAddress(),
|
|
1229
|
+
caller: opts.caller,
|
|
1230
|
+
value: opts.value,
|
|
1231
|
+
depth: opts.depth,
|
|
1232
|
+
selfdestruct: opts.selfdestruct ?? new Map(),
|
|
1233
|
+
isStatic: opts.isStatic,
|
|
1234
|
+
blobVersionedHashes: opts.blobVersionedHashes,
|
|
1235
|
+
})
|
|
1236
|
+
|
|
1237
|
+
return this.runInterpreter(message, { pc: opts.pc })
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* Returns the precompile function registered at the given address,
|
|
1242
|
+
* or `undefined` if no precompile is active there.
|
|
1243
|
+
*
|
|
1244
|
+
* Accepts either an `Address` instance or a `0x`-prefixed hex string.
|
|
1245
|
+
*
|
|
1246
|
+
* ```ts
|
|
1247
|
+
* const evm = await createEVM({
|
|
1248
|
+
* customPrecompiles: [{ address: '0x000000000000000000000000000000000000ff01', function: myFn }],
|
|
1249
|
+
* })
|
|
1250
|
+
* const fn = evm.getPrecompile('0x000000000000000000000000000000000000ff01')
|
|
1251
|
+
* ```
|
|
1252
|
+
*/
|
|
1253
|
+
getPrecompile(address: Address | PrefixedHexString): PrecompileFunc | undefined {
|
|
1254
|
+
if (typeof address === 'string') {
|
|
1255
|
+
return this.precompiles.get(address.slice(2).padStart(40, '0').toLowerCase())
|
|
1256
|
+
}
|
|
1257
|
+
return this.precompiles.get(bytesToUnprefixedHex(address.bytes))
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* Executes a precompiled contract with given data and gas limit.
|
|
1262
|
+
*/
|
|
1263
|
+
protected runPrecompile(
|
|
1264
|
+
code: PrecompileFunc,
|
|
1265
|
+
data: Uint8Array,
|
|
1266
|
+
gasLimit: bigint,
|
|
1267
|
+
): Promise<ExecResult> | ExecResult {
|
|
1268
|
+
if (typeof code !== 'function') {
|
|
1269
|
+
throw EthereumJSErrorWithoutCode('Invalid precompile')
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
const opts = {
|
|
1273
|
+
data,
|
|
1274
|
+
gasLimit,
|
|
1275
|
+
common: this.common,
|
|
1276
|
+
_EVM: this,
|
|
1277
|
+
_debug: this.DEBUG ? debugPrecompiles : undefined,
|
|
1278
|
+
stateManager: this.stateManager,
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
return code(opts)
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
protected async _loadCode(message: Message): Promise<void> {
|
|
1285
|
+
if (!message.code) {
|
|
1286
|
+
const precompile = this.getPrecompile(message.codeAddress)
|
|
1287
|
+
if (precompile) {
|
|
1288
|
+
message.code = precompile
|
|
1289
|
+
message.isCompiled = true
|
|
1290
|
+
} else {
|
|
1291
|
+
message.code = await this.stateManager.getCode(message.codeAddress)
|
|
1292
|
+
|
|
1293
|
+
// EIP-7702 delegation check
|
|
1294
|
+
if (
|
|
1295
|
+
this.common.isActivatedEIP(7702) &&
|
|
1296
|
+
equalsBytes(message.code.slice(0, 3), DELEGATION_7702_FLAG)
|
|
1297
|
+
) {
|
|
1298
|
+
const address = new Address(message.code.slice(3, 24))
|
|
1299
|
+
message.code = await this.stateManager.getCode(address)
|
|
1300
|
+
// EIP-7928: Track delegation target access in BAL
|
|
1301
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1302
|
+
this.blockLevelAccessList?.addAddress(address.toString())
|
|
1303
|
+
}
|
|
1304
|
+
if (message.depth === 0) {
|
|
1305
|
+
this.journal.addAlwaysWarmAddress(address.toString())
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
message.isCompiled = false
|
|
1310
|
+
message.chargeCodeAccesses = true
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
protected async _generateAddress(message: Message): Promise<Address> {
|
|
1316
|
+
let addr
|
|
1317
|
+
if (message.salt) {
|
|
1318
|
+
addr = generateAddress2(message.caller.bytes, message.salt, message.code as Uint8Array)
|
|
1319
|
+
} else {
|
|
1320
|
+
let acc = await this.stateManager.getAccount(message.caller)
|
|
1321
|
+
if (!acc) {
|
|
1322
|
+
acc = new Account()
|
|
1323
|
+
}
|
|
1324
|
+
const newNonce = acc.nonce - BIGINT_1
|
|
1325
|
+
addr = generateAddress(message.caller.bytes, bigIntToBytes(newNonce))
|
|
1326
|
+
}
|
|
1327
|
+
return new Address(addr)
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
protected async _reduceSenderBalance(account: Account, message: Message): Promise<void> {
|
|
1331
|
+
const originalBalance = account.balance
|
|
1332
|
+
account.balance -= message.value
|
|
1333
|
+
if (account.balance < BIGINT_0) {
|
|
1334
|
+
throw new EVMError(EVMError.errorMessages.INSUFFICIENT_BALANCE)
|
|
1335
|
+
}
|
|
1336
|
+
// EIP-7928: Record the sender's reduced balance in BAL
|
|
1337
|
+
// Per spec, CALL/CALLCODE senders must have their balance recorded
|
|
1338
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1339
|
+
this.blockLevelAccessList!.addBalanceChange(
|
|
1340
|
+
message.caller.toString(),
|
|
1341
|
+
account.balance,
|
|
1342
|
+
this.blockLevelAccessList!.blockAccessIndex,
|
|
1343
|
+
originalBalance,
|
|
1344
|
+
)
|
|
1345
|
+
}
|
|
1346
|
+
const result = this.journal.putAccount(message.caller, account)
|
|
1347
|
+
if (this.DEBUG) {
|
|
1348
|
+
debug(`Reduced sender (${message.caller}) balance (-> ${account.balance})`)
|
|
1349
|
+
}
|
|
1350
|
+
return result
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
protected async _addToBalance(toAccount: Account, message: MessageWithTo): Promise<void> {
|
|
1354
|
+
const originalBalance = toAccount.balance
|
|
1355
|
+
const newBalance = toAccount.balance + message.value
|
|
1356
|
+
if (newBalance > MAX_INTEGER) {
|
|
1357
|
+
throw new EVMError(EVMError.errorMessages.VALUE_OVERFLOW)
|
|
1358
|
+
}
|
|
1359
|
+
toAccount.balance = newBalance
|
|
1360
|
+
if (this.common.isActivatedEIP(7928)) {
|
|
1361
|
+
this.blockLevelAccessList!.addAddress(message.to.toString())
|
|
1362
|
+
if (message.value !== BIGINT_0) {
|
|
1363
|
+
this.blockLevelAccessList!.addBalanceChange(
|
|
1364
|
+
message.to.toString(),
|
|
1365
|
+
newBalance,
|
|
1366
|
+
this.blockLevelAccessList!.blockAccessIndex,
|
|
1367
|
+
originalBalance,
|
|
1368
|
+
)
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
// putAccount as the nonce may have changed for contract creation
|
|
1372
|
+
await this.journal.putAccount(message.to, toAccount)
|
|
1373
|
+
if (this.DEBUG) {
|
|
1374
|
+
debug(`Added toAccount (${message.to}) balance (-> ${toAccount.balance})`)
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* Once the interpreter has finished depth 0, a post-message cleanup should be done
|
|
1380
|
+
*/
|
|
1381
|
+
private postMessageCleanup() {
|
|
1382
|
+
if (this.common.isActivatedEIP(1153)) this.transientStorage.clear()
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
/**
|
|
1386
|
+
* This method copies the EVM, current HF and EIP settings
|
|
1387
|
+
* and returns a new EVM instance.
|
|
1388
|
+
*
|
|
1389
|
+
* Note: this is only a shallow copy and both EVM instances
|
|
1390
|
+
* will point to the same underlying state DB.
|
|
1391
|
+
*
|
|
1392
|
+
* @returns EVM
|
|
1393
|
+
*/
|
|
1394
|
+
public shallowCopy(): EVM {
|
|
1395
|
+
const common = this.common.copy()
|
|
1396
|
+
common.setHardfork(this.common.hardfork())
|
|
1397
|
+
|
|
1398
|
+
const opts = {
|
|
1399
|
+
...this._optsCached,
|
|
1400
|
+
common,
|
|
1401
|
+
stateManager: this.stateManager.shallowCopy(),
|
|
1402
|
+
}
|
|
1403
|
+
// @ts-expect-error -- Assigning a StateManager property that is absent from the interface
|
|
1404
|
+
opts.stateManager['common'] = common
|
|
1405
|
+
return new EVM(opts)
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
public getPerformanceLogs() {
|
|
1409
|
+
return this.performanceLogger.getLogs()
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
public clearPerformanceLogs() {
|
|
1413
|
+
this.performanceLogger.clear()
|
|
1414
|
+
}
|
|
1415
|
+
}
|