1/5
_Follow along with this video:_ --- Alright! We've gone op code by op code and break down our Solidity contract's bytecode. At this point we could maybe even decompile our contract back into some semblence of Solidity code by following through the execution! This isn't something we necessarily have to do ourselves though. There exist tool such as [Dedaub](https://app.dedaub.com/decompile) that can try to decompile byte code for us! Let's try entering our contract's runtime code into this tool and see how it does (it may take a few minutes to decompile). ``` runtime code - 0x6080604052348015600e575f80fd5b50600436106030575f3560e01c8063cdfead2e146034578063e026c017146045575b5f80fd5b6043603f3660046059565b5f55565b005b5f5460405190815260200160405180910390f35b5f602082840312156068575f80fd5b503591905056fea2646970667358 ``` Solidity Contract: ```js // SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.20; contract HorseStore { uint256 numberOfHorses; function updateHorseNumber(uint256 newNumberOfHorses) external { numberOfHorses = newNumberOfHorses; } function readNumberOfHorses() external view returns (uint256) { return numberOfHorses; } } ``` Dedaub result: ```js uint256 stor_0; // STORAGE[0x0] function function_selector() public payable { revert(); } function 0xcdfead2e(uint256 varg0) public payable { require(msg.data.length - 4 >= 32); stor_0 = varg0; } function 0xe026c017() public payable { return stor_0; } // Note: The function selector is not present in the original solidity code. // However, we display it for the sake of completeness. function function_selector( function_selector) public payable { MEM[64] = 128; require(!msg.value); if (msg.data.length >= 4) { if (0xcdfead2e == function_selector >> 224) { 0xcdfead2e(); } else if (0xe026c017 == function_selector >> 224) { 0xe026c017(); } } fallback(); } ``` So it's .. not great, but we can definitely see the flavour of what our Solidity contract was doing. We see the `0xcdfead2e` function taking a uint256, and storing that at storage slot 0 - this is our `setNumberOfHorses` function! We can also see the `0xe026c017` function returning a value from storage slot 0, this is of course our `readNumberOfHorses` function. You can also check out [Heimdal-RS](https://github.com/Jon-Becker/heimdall-rs) as another option for decompiling bytecode!
A comprehensive introduction to smart contract decompilation and disassembly, in which the user learns how to read and understand the underlying bytecode of a smart contract. The lesson covers topics such as opcodes, how opcodes function in Solidity, and demonstrates using the Dedub and Heimdall-rs tools to decompile bytecode back into Solidity.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Assembly
Writing smart contracts using Huff and Yul
Ethereum Virtual Machine OPCodes
Formal verification testing
Smart contract invariant testing
Halmos, Certora, Kontrol
Security researcher
$49,999 - $120,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Guest lecturers:
Josselin Feist
Head of Blockchain at Trail of Bits
Last updated on January 17, 2025
Solidity Developer
Assembly and Formal VerificationDuration: 30min
Duration: 4h 38min
Duration: 3h 57min
Duration: 1h 56min
Course Overview
About the course
Assembly
Writing smart contracts using Huff and Yul
Ethereum Virtual Machine OPCodes
Formal verification testing
Smart contract invariant testing
Halmos, Certora, Kontrol
Security researcher
$49,999 - $120,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Guest lecturers:
Josselin Feist
Head of Blockchain at Trail of Bits
Last updated on January 17, 2025
Testimonials
Read what our students have to say about this course.
Chainlink
Chainlink
Gustavo Gonzalez
Solutions Engineer at OpenZeppelin
Francesco Andreoli
Lead Devrel at Metamask
Albert Hu
DeForm Founding Engineer
Radek
Senior Developer Advocate at Ceramic
Boidushya
WalletConnect
Idris
Developer Relations Engineer at Axelar