Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Current code is not compatible with solidity version 0.8.0 #22041

Closed
Chengru-Song opened this issue Dec 20, 2020 · 0 comments · Fixed by #22092
Closed

Current code is not compatible with solidity version 0.8.0 #22041

Chengru-Song opened this issue Dec 20, 2020 · 0 comments · Fixed by #22092

Comments

@Chengru-Song
Copy link

System information

Geth version: geth version
Solidity version: 0.8.0
OS & Version: Windows/Linux/OSX
Commit hash : (if develop)

Expected behaviour

https://github.com/ethereum/go-ethereum/blob/3c46f5570bd674cf49c0113352ff79a4e026a5b8/common/compiler/solidity.go#L143
When executing this line, the json string is expected to marshal in the output struct where abi is of type string. The abi string will be further marshalled into another struct and the process should report no error if compiled with solc command(which is solidity compiler).

Actual behaviour

When compiled with solidity v0.8.0, it will produce the following unmarshal error:
json: cannot unmarshal array into Go struct field .Contracts.Abi of type string

Steps to reproduce the behaviour

Try deploy the smart contracts with compiler, execute this line of code:
contracts, err := compiler.CompileSolidity("./solc-macos", path...)
The following is a deploy example:

    t.Log("test deploy contract")
    // Configure and generate a sample block chain
    var (
        memDb   = memorydb.New()
        db      = rawdb.NewDatabase(memDb)
        key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
        address = crypto.PubkeyToAddress(key.PublicKey)
        gspec   = &core.Genesis{
            GasLimit: 800000000,
            Config: &params.ChainConfig{
                HomesteadBlock:      big.NewInt(0),
                EIP150Block:         big.NewInt(0),
                EIP155Block:         big.NewInt(0),
                EIP158Block:         big.NewInt(0),
                ByzantiumBlock:      big.NewInt(0),
                ConstantinopleBlock: big.NewInt(0),
                PetersburgBlock:     big.NewInt(0),
                IstanbulBlock:       big.NewInt(0),
            },
            Alloc: core.GenesisAlloc{
                address: {Balance: big.NewInt(9000000000000000000)},
            },
        }
    )
    engine := ethash.NewFaker()
    chainConfig, _, err := core.SetupGenesisBlock(db, gspec)
    if err != nil {
        t.Fatal(err)
    }
    blockchain, err := core.NewBlockChain(db, &core.CacheConfig{
        TrieDirtyDisabled: true,
    }, chainConfig, engine, vm.Config{}, nil)
    if err != nil {
        t.Fatal(err)
    }
    _ = blockchain.StateCache().TrieDB()
    // construct the first diff

    contractBackend := backends.NewSimulatedBackend(gspec.Alloc, gspec.GasLimit)
    transactOpts := bind.NewKeyedTransactor(key)
    transactOpts.GasPrice = big.NewInt(1)
    _ = transactOpts
    _ = contractBackend
    source := []string{"/Users/bytedance/Documents/codes/bsol/WeatherStorage.sol"}
    contracts, err := compiler.CompileSolidity("./solc-macos", path...)
    if err != nil {
        return nil, err
    }
    var data []ContractData
    for contractName, contract := range contracts {
        fmt.Println(contractName)
        if strings.Index(strings.Split(contractName, ":")[1], "Benchmark") != 0 {
            continue
        }
        var names []string
        abiData, err := json.Marshal(contract.Info.AbiDefinition.([]interface{}))
        if err != nil {
            return nil, err
        }
        abi, err := abi.JSON(bytes.NewBuffer(abiData))
        if err != nil {
            return nil, err
        }
        // fmt.Printf("abi: %+v\nabiData:%+v\n", abi, abiData)
        for _, method := range contract.Info.AbiDefinition.([]interface{}) {
            mapped := method.(map[string]interface{})
            if mapped["name"] == nil {
                if len(mapped["inputs"].([]interface{})) != 0 {
                    return nil, errors.New("Invalid Benchmark: constructor should require 0 arguments")
                }
                continue
            }
            name := mapped["name"].(string)
            if strings.Index(name, "Benchmark") != 0 {
                continue
            }
            if len(mapped["inputs"].([]interface{})) != 0 {
                return nil, errors.New("Invalid Benchmark: %s: function should require 0 arguments, but it requires %d")
            }
            names = append(names, name)
        }
        if err != nil {
            return nil, err
        }
        data = append(data, ContractData{abi, contract.Code, names, strings.Split(contractName, ":")[1]})
    }
    contractBackend.Commit()
    return data, nil

Suggestion

For developers, please try to modify the output behavior of solidity 0.8.0 compiler from outputing array to string, or try to modify the https://github.com/ethereum/go-ethereum/blob/3c46f5570bd674cf49c0113352ff79a4e026a5b8/common/compiler/solidity.go#L141 function to make it compatible with the new solidity compiler version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants