UNPKG

contract-splitter

Version:

Split an EVM smart contract deployement bytecode into its sub components

49 lines (42 loc) 1.61 kB
module.exports = function (input) { input = input.toLowerCase().replace("0x", ""); // Look for a special pattern of contract deployement tx present at the end of the constructor bytecode // 0x5B JUMPDEST (OPTIONAL) // 0x60 PUSH1 / 0x61 PUSH2 / 0x62 PUSH3 : This is the contract bytecode length // 0x80 DUP1 // 0x60 PUSH1 / 0x61 PUSH2 / 0x62 PUSH3 : This the the contract bytecode offset // 0x60 0x00 PUSH1 (0) // 0x39 CODECOPY // 0x60 0x00 PUSH1 (0) // 0xF3 RETURN // 0xFE INVALID const CODECOPY_REGEX = /(?:5b)?(?:60([a-z0-9]{2})|61([a-z0-9_]{4})|62([a-z0-9_]{6}))80(?:60([a-z0-9]{2})|61([a-z0-9_]{4})|62([a-z0-9_]{6}))6000396000f3fe/gm; m = CODECOPY_REGEX.exec(input); if (m == null || m == undefined) { throw Error("Input is not a standard deployement bytecode"); } const CONSTRUCTOR_OFFSET = 0; const CONTRACT_LENGTH = parseInt(m[1] || m[2] || m[3], 16) * 2; const CONTRACT_OFFSET = parseInt(m[4] || m[5] || m[6], 16) * 2; // Also get embedded metadata from the contract's code : located at the end of it const METADATA_LENGTH = parseInt( input.slice( CONTRACT_OFFSET + CONTRACT_LENGTH - 4, CONTRACT_OFFSET + CONTRACT_LENGTH ), 16 ) * 2 + 4; return { constructor: input.slice(CONSTRUCTOR_OFFSET, CONTRACT_OFFSET), contract: input.slice(CONTRACT_OFFSET, CONTRACT_OFFSET + CONTRACT_LENGTH), metadata: input.slice( CONTRACT_OFFSET + CONTRACT_LENGTH - METADATA_LENGTH, CONTRACT_OFFSET + CONTRACT_LENGTH ), arguments: input.slice(CONTRACT_OFFSET + CONTRACT_LENGTH), }; };