{"_id":"@bradthomasbrown/evm-asm","_rev":"2-ebe79beb8bb2df6c1c7f1d3dbaafeaed","name":"@bradthomasbrown/evm-asm","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@bradthomasbrown/evm-asm","version":"1.0.0","author":{"name":"Brad Brown","email":"https://t.me/bradthomasbrown"},"_id":"@bradthomasbrown/evm-asm@1.0.0","maintainers":[{"name":"bradthomasbrown","email":"bradthomasbrown@outlook.com"}],"dist":{"shasum":"13c513bfa86b07b6811424527b0a5d4135481e24","tarball":"https://registry.npmjs.org/@bradthomasbrown/evm-asm/-/evm-asm-1.0.0.tgz","fileCount":5,"integrity":"sha512-CjxdwzmZRe9B0NPOTXKc1pqubjyk0y2WsQNbIJPZNwQhwNp6SyyVBWp/1TyybzPstUFWwAma7BKDY7fusX+djw==","signatures":[{"sig":"MEQCIHn5M944Ia67QgTtsLifL9vdgNzt4KpPW9n2KiICZReOAiBZhVBznbIsMpx5e+4suFbimAxTX0lA1zCjVpAuNdfHtQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15634},"type":"module","exports":{".":"./dist/evm-asm.js"},"gitHead":"3f54fc2f33361071ff725f3f4d3a39df1d2c201c","_npmUser":{"name":"bradthomasbrown","email":"bradthomasbrown@outlook.com"},"_npmVersion":"10.9.2","description":"Minimal, unoptimized, unaudited, and experimental Ethereum/EVM assembler in JavaScript/TypeScript.","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/evm-asm_1.0.0_1766487457080_0.17281031557740456","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bradthomasbrown/evm-asm","description":"Minimal, unoptimized, unaudited, and experimental Ethereum/EVM assembler in JavaScript/TypeScript.","version":"1.0.1","author":{"name":"Brad Brown","email":"https://t.me/bradthomasbrown"},"type":"module","exports":{".":"./dist/evm-asm.js"},"_id":"@bradthomasbrown/evm-asm@1.0.1","gitHead":"70ec94b508bae1497c6df59c4efab650d9e2eaba","_nodeVersion":"22.16.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-PdIfJde7aqOQNFO01WkWd5H8gKGdDL9sa07N5UoPL3OBq4uJ6XQqmuyVvQ9EgUem7EagIEeEVm75Eaf6qpCjeg==","shasum":"4fa4e85b45bb891a6660ff277771c465517b02f8","tarball":"https://registry.npmjs.org/@bradthomasbrown/evm-asm/-/evm-asm-1.0.1.tgz","fileCount":5,"unpackedSize":15814,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDucXWcKOvvgH8eyLHvqsnQAkUREyjZOmqCuNosiuJdsAIhAJBstIfe0xRRbFz4fyAdUw0zHN4DdfWBM9fm760OXYdf"}]},"_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-asm_1.0.1_1766527300400_0.32107252492244887"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-23T10:57:36.972Z","modified":"2025-12-23T22:01:40.714Z","1.0.0":"2025-12-23T10:57:37.230Z","1.0.1":"2025-12-23T22:01:40.544Z"},"author":{"name":"Brad Brown","email":"https://t.me/bradthomasbrown"},"description":"Minimal, unoptimized, unaudited, and experimental Ethereum/EVM assembler in JavaScript/TypeScript.","maintainers":[{"name":"bradthomasbrown","email":"bradthomasbrown@outlook.com"}],"readme":"# evm-asm\r\nThis is a simple, minimal, and experimental Ethereum/EVM assembler in TypeScript/JavaScript. \r\n\r\n## Why?\r\nI think it's important to know how smart contracts actually work. However, writing bytecode by hand can suck a bit. Reading handwritten bytecode can be very difficult.\r\nAn assembler makes it so more readable files can be produced and it takes a lot of guesswork and trial-and-error out of handwriting bytecode and chasing down program counters and addresses.\r\n\r\n# Notes\r\n**This is highly untested, unstable, and incomplete.**<br>\r\nWe wrote an assembler before, this is a more recent rewriting. The new rewriting uses a lexer-parser style of intake rather than a fixed-width style of intake, allowing for more flexible formatting.\r\nWe also allowed dangling references and a mapping parameter so that such references can be converted into literals, allowing shorthand references to be written as if we were referring to labels, but we can substitute in\r\nentire addresses or bytecode strings.\r\nThe below usage example uses a very mildly adapted version of EVM assembly we wrote a while ago (handwritten) for a CREATE2 contract.\r\n\r\n## Installation\r\n```sh\r\nnpm i @bradthomasbrown/evm-asm\r\n```\r\n\r\n## Usage\r\n- `instructions` or `opcodes` are just the matching string from any EVM opcode reference, like `RETURNDATASIZE`, `CALLER`, `PUSH1`, etc.\r\n- labels are anything else which end in a colon (`:`)\r\n- hex literals are anything else which consist of an even amount of hexidecimal characters\r\n- identifiers are anything else, which default to being references to a label, but can be \"dangling\" and used to substitute a hex string in via a mapping parameter\r\n- **NOTE**: the `RUN:` label is a special label. For contract deployment, this is required in order to resolve and differentiate between labels and references in the `init` or `make` section of contract deployment and those in the `run` section of contract execution.\r\n```js\r\nimport { _228529_ } from \"@bradthomasbrown/evm-asm.js\";\r\n\r\nconst code = `\r\n#-MAKE----------# copy runcode to mem, trickle runcode size\r\nPUSH1 RUNSIZE   # 00    # 60?r  #       ret size, trickle, ?r=57\r\nDUP1            # 02    # 80    #       cc size\r\nPUSH1 09        # 03    # 6009  #       cc offset\r\nRETURNDATASIZE  # 05    # 3d    #       cc destOffset\r\nCODECOPY        # 06    # 39    #   cc m00,?r=runcode\r\n#---------------# return runcode from mem\r\nRETURNDATASIZE  # 07    # 3d    #       ret offset\r\nRETURN          # 08    # f3    #   ret\r\nRUN: #----------# if (calldatasize) goto ?c else goto ?l\r\nCALLDATASIZE    # 00    # 36    #       ji b [b]\r\nPUSH1 ?c        # 01    # 60?c  #       ji counter [counter, b] ?c=0b\r\nJUMPI           # 03    # 57    #   ji []\r\n?l: #-----------# load slot 0 to mem at 00\r\nRETURNDATASIZE  # 04    # 3d    #           sl key\r\nSLOAD           # 05    # 54    #       ms value, sl\r\nRETURNDATASIZE  # 06    # 3d    #       ms offset\r\nMSTORE          # 07    # 52    #   ms m00,20=address\r\n#---------------# return slot 0\r\nMSIZE           # 08    # 59    #       ret size\r\nRETURNDATASIZE  # 09    # 3d    #       ret offset\r\nRETURN          # 0a    # f3    #   ret\r\n?c: #-----------# if (caller == deployer) goto ?d else goto ?s\r\nJUMPDEST        # 0b    # 5b    #\r\nCALLER          # 0c    # 33    #           eq b\r\nPUSH20 ?D       # 0d    # 73?D  #           eq a, ?D=?D??????????????????????????????????????\r\nEQ              # 22    # 14    #       ji b, eq\r\nPUSH1 ?d        # 23    # 60?d  #       ji counter ?d=27\r\nJUMPI           # 25    # 57    #   ji []\r\n?s: #-----------# halt\r\nSTOP            # 26    # 00    #   stop\r\n?d: #-----------# copy code to mem, trickle code size\r\nJUMPDEST        # 27    # 5b    #\r\nPUSH1 20        # 28    # 6020  #           sub b [b]\r\nCALLDATASIZE    # 2a    # 36    #           sub a [a, b]\r\nSUB             # 2b    # 03    #       cdc size, sub [size]\r\nPUSH1 20        # 2c    # 6020  #       cdc offset [offset, size]\r\nRETURNDATASIZE  # 2e    # 3d    #       cdc destOffset [destOffset, offset, size]\r\nCALLDATACOPY    # 2f    # 37    #   cdc m00,size=code []\r\n#---------------# deploy first implementation, store address in slot 0\r\nMSIZE           # 30    # 59    #           c size [size]\r\nRETURNDATASIZE  # 31    # 3d    #           c offset [offset, size]\r\nRETURNDATASIZE  # 32    # 3d    #           c value [value, offset, size]\r\nCREATE          # 33    # f0    #       ss value, c [address]\r\nRETURNDATASIZE  # 34    # 3d    #       ss key [key, address]\r\nSSTORE          # 35    # 55    #   ss [] s0=address\r\n#---------------# save generic init to mem\r\nPUSH19 ?x       # 36    # 72?x  #       ms value, x=6020343434335afa3451803b343482933c34f3 [value, offset]\r\nRETURNDATASIZE  # 4a    # 3d    #       ms offset [offset, value]\r\nMSTORE          # 4b    # 52    #   ms 0d,20=init []\r\n#---------------# deploy generic init\r\nRETURNDATASIZE  # 4c    # 3d    #           cdl i\r\nCALLDATALOAD    # 4d    # 35    #       cdl [salt]\r\nPUSH1 13        # 4e    # 6013  #       [size, salt]\r\nPUSH1 0d        # 50    # 600d  #       [offset, size, salt]\r\nCALLVALUE       # 52    # 34    #       c2 value [value, offset, size, salt]\r\nCREATE2         # 53    # f5    #   c2 [_address]\r\n#---------------# clear slot 0\r\nRETURNDATASIZE  # 54    # 3d    #       ss value\r\nRETURNDATASIZE  # 55    # 3d    #       ss key\r\nSSTORE          # 56    # 55    #   ss s0=0\r\n`;\r\n\r\nconsole.log(assemble(code, {\r\n    \"?D\": \"0102030401020304010203040102030401020304\",\r\n    \"?x\": \"6020343434335afa3451803b343482933c34f3\"\r\n}));\r\n// 60578060093d393df336600b573d543d52593df35b3373010203040102030401020304010203040102030414602757005b6020360360203d37593d3df03d55726020343434335afa3451803b343482933c34f33d523d356013600d34f53d3d55\r\n```","readmeFilename":"README.md"}