0

I have a file that is composed of multiple imports, too much code to drop here so I will illustrate my question with a very simplified example. My compilers:

$ abigen --version
abigen version 1.11.7-unstable-d3ece3a0-20230421
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.8.25+commit.b61c2a91.Linux.g++

This is my main.go

package main

import (
    "fmt"
    "log"
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    // Define paths
    contractFileName := "Test"
    contractFile := "./sol/" + contractFileName + ".sol" // Path to the Solidity contract
    outputDir := "./solc-output"                         // Directory to store ABI and BIN files
    apiDir := "./api"                                    // Directory to store generated Go bindings
    generatedFileName := "Meow"
    generatedPackageName := "api"

    // Ensure output and API directories exist
    err := os.MkdirAll(outputDir, os.ModePerm)
    if err != nil {
        log.Fatalf(" %v\n: %s not writable", err, outputDir)
    }
    err = os.MkdirAll(apiDir, os.ModePerm)
    if err != nil {
        log.Fatalf(" %v\n: %s not writable", err, outputDir)
    }

    // Compile the contract using solc
    cmd := exec.Command("solc", "--optimize", "--abi", "--bin", "--overwrite", "--output-dir", outputDir, contractFile)
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatalf("Failed to compile contract: %v\nOutput: %s", err, string(output))
    }
    fmt.Println("Contract compiled successfully")

    // Find all ABI files
    abiFiles, err := filepath.Glob(filepath.Join(outputDir, "*.abi"))
    if err != nil {
        panic(err) // Handle error appropriately in real usage
    }

    // Find all BIN files
    binFiles, err := filepath.Glob(filepath.Join(outputDir, "*.bin"))
    if err != nil {
        panic(err) // Handle error appropriately in real usage
    }

    // Read and concatenate all ABI files
    var mergedABI []byte
    for _, file := range abiFiles {
        abi, err := os.ReadFile(file)
        if err != nil {
            panic(err) // Handle error appropriately in real usage
        }
        mergedABI = append(mergedABI, abi...)
    }

    // Read and concatenate all BIN files
    var mergedBIN []byte
    for _, file := range binFiles {
        bin, err := os.ReadFile(file)
        if err != nil {
            panic(err) // Handle error appropriately in real usage
        }
        mergedBIN = append(mergedBIN, bin...)
    }

    // Write merged ABI and BIN files
    mergedABIFilename := filepath.Join(outputDir, "Merged.abi")
    mergedBINFilename := filepath.Join(outputDir, "Merged.bin")
    err = os.WriteFile(mergedABIFilename, mergedABI, 0600) //nolint:gomnd
    if err != nil {
        panic(err) // Handle error appropriately in real usage
    }
    err = os.WriteFile(mergedBINFilename, mergedBIN, 0600) //nolint:gomnd
    if err != nil {
        panic(err) // Handle error appropriately in real usage
    }
    // Generate Go bindings using abigen
    outFile := filepath.Join(apiDir, generatedFileName+".go")

    cmd = exec.Command("abigen", "--bin="+mergedBINFilename, "--abi="+mergedABIFilename, "--pkg="+generatedPackageName, "--type="+generatedFileName, "--out="+outFile) //nolint:lll,gosec
    output, err = cmd.CombinedOutput()
    if err != nil {
        log.Fatalf("Failed to generate Go bindings: %v\nOutput: %s", err, string(output))
    }
    fmt.Println("Go bindings generated successfully")
}

My Test.sol file:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract Cat{
    uint private x;
    constructor(){}
    function myFunction() external{
        x = 3;
    }
}

contract Kitten is Cat{
    constructor(){}
}

The code runs properly and compiles ABI and BIN files that are used by abigen to compile a Go file. These files are the ones generated by solc and then merged. The Merged.abi

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"myFunction","outputs":[],"stateMutability":"nonpayable","type":"function"}][{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"myFunction","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Here's the Merged.bin

6080604052348015600e575f80fd5b50606a80601a5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063c3780a3a14602a575b5f80fd5b603260035f55565b00fea26469706673582212209b498247d95b06f9aa10532b25e9928ac955a571fbad018b3d81df5c16a5913964736f6c634300081900336080604052348015600e575f80fd5b50606a80601a5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063c3780a3a14602a575b5f80fd5b603260035f55565b00fea26469706673582212204d91517e152fd222d9d185cba0f638c374c2c77d3a5a9c0857a92f455a8d0eb564736f6c63430008190033

Then I have deployed the Test.sol on the Sepolia and verified the code. This is the deployed Contract ABI.

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"myFunction","outputs":[],"stateMutability":"nonpayable","type":"function"}]

And this is the Contract Creation Code

6080604052348015600e575f80fd5b50607180601a5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063c3780a3a14602a575b5f80fd5b60306032565b005b60035f8190555056fea26469706673582212202b9627ac3a9c53ea54bd8e42f94149b86c8eb2858950889ddbfb65eaafc18dd164736f6c63430008190033

The merged ABI and BIN files generated by solc are not identical to the ABI and BIN files generated on Etherscan.

It is my expectation that ABI files should be identical and so should the BIN files.

This does not give me great confidence in using the Go file compiled by abigen since the merged source files used as arguments are not the same as the verified contract.

Any insight on how to resolve this?

1 Answer 1

1

If you compile only Kitten.sol using solc. It’ll generate the identical ABI and BIN files to what you’re getting on Etherscan.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.