Ethereum: Debugging Binary Differences between Local and Remix
As a Solidity developer, you’re not alone in noticing differences in binary output between local compilation with Truffle’s solc compiler and deploying to the Ethereum network using Remix. In this article, we’ll explore what causes these discrepancies and provide guidance on how to troubleshoot and resolve them.
The Issue: Different Binary Formats
When you compile your Solidity code using solc (Solidity Compiler) locally, it produces a binary file with a specific format that’s compatible only with the local machine’s architecture. However, when you deploy your contract to the Ethereum network using Remix, the same source code is compiled into different binaries due to differences in the Solana blockchain’s native compiler and the Ethereum Virtual Machine (EVM) requirements.
The Problem: solc Compiler Version
A potential cause of these binary differences is a mismatch between the version of the solc compiler being used locally versus what Remix is using. The solc
compiler version might not be compatible with your local setup, leading to different binary outputs when compiling and deploying on both platforms.
Testing with Remix
To verify this hypothesis, we can test the scenario with Remix, which has its own native Solana compiler (solana
). We’ll create a new contract and deploy it using Remix, then compare the binary output to what’s produced locally.
Here’s an updated version of your code:
pragma solidity 0.8.20;
contract HelloWorld {
function test() public pure returns (bool) {}
}
// Deployment with Remix
function main() public payable {
HelloWorld memory hello = Hello();
require(hello.test() == true, "hello");
}
Deployment to Remix
We’ll use the web3.js
library in Remix to interact with the local machine’s blockchain and deploy our contract using a new account. The deployment process might produce different binaries depending on the Solana compiler used.
Testing with solc Compiler Version
Now, let’s test this scenario by comparing the binary output produced locally versus when we use Remix.
Local Compilation
cd ~/Truffle
solc -v solidity-0.8.20.js --bin HelloWorld.js
Remix Deployment (with solana)
To deploy our contract using Remix, we’ll create a new account on the Solana blockchain and interact with it to test our deployment.
const { Web3 } = require('web3');
const web3 = new Web3();
async function main() {
const networkName = 'mainnet';
const accountAddress = '0x...'; // Replace with your own Solana address
try {
const transactionCount = await web3.eth.getTransactionCount(accountAddress);
const tx = await web3.eth.sendTransaction({
from: accountAddress,
to: '0x...', // Replace with the recipient's address
value: web3.utils.toWei('1', 'ether'),
gas: 200000,
gasPrice: 20,
});
console.log(tx);
} catch (error) {
console.error(error);
}
}
main();
Compare Binary Outputs
We can compare the binary output produced locally and when we use Remix to identify any differences.
Output Comparison
When we run the code in local mode, we might see a different binary format compared to what we deploy with Remix. Let’s take a look at the potential differences:
$ objdump -h HelloWorld_0x12345678.bin
file format bin
We’ll compare the output of objdump
for both scenarios.
In this example, the HelloWorld_0x12345678.bin
binary produced locally has a different structure and layout compared to what’s deployed with Remix. This difference might be caused by the Solana compiler used in Remix versus the solc compiler being used locally.