

今まではRemixかTruffleを使って、SmartcontractのDeployを実行していました。  
PythonでDeploy出来ればいいなと思い、py-solc-xを使うことにしました。  
そこで起きた問題が解決出来ずに、今回お力を貸していただきたいです。

pythonから抜粋

[code]

     compile_source(source, output_values=["abi", "bin"], solc_version=_solc_version)
    
    中略
    
        tx = contract.constructor("Hi!").build_transaction(
            dict(
                chainId=web3_connect.connect_provider["chain_id"],
                nonce=w3.eth.getTransactionCount(FROM_ADDRESS),
                type=2,
                gas=1000000,
                maxFeePerGas=web3_connect.gwei_to_wei(math.ceil(gas_station["maxFee"])),
                maxPriorityFeePerGas=web3_connect.gwei_to_wei(math.ceil(gas_station["maxPriorityFee"])),
            )
        )
    
[/code]

solidity

[code]

    pragma solidity ^0.8.0;
    
    contract Test {
        string public msg;
    
        constructor(string memory message) {
            msg = message;
        }
    
        function greet() public view returns (string memory) {
            return msg;
        }
    }
    
[/code]

上記のケースでは正常にdeployすることが出来ました。

solidityに新たなVersionクラスを追加し継承させました。

[code]

    pragma solidity ^0.8.0;
    
    contract Version {
        string private _version;
    
        constructor(string memory version_) {
            _version = version_;
        }
    
        function version() external view returns (string memory) {
            return _version;
        }
    }
    
    contract Test is Version {
        string public msg;
    
        constructor(string memory message, string memory version) Version(version) {
            msg = message;
        }
    
        function greet() public view returns (string memory) {
            return msg;
        }
    }
    
[/code]

constructorの引数が増えているので、pythonを以下のように変更しました。

[code]

        tx = contract.constructor("Hi!", "1.0.0").build_transaction(
            dict(
                chainId=web3_connect.connect_provider["chain_id"],
                nonce=w3.eth.getTransactionCount(FROM_ADDRESS),
                type=2,
                gas=1000000,
                maxFeePerGas=web3_connect.gwei_to_wei(math.ceil(gas_station["maxFee"])),
                maxPriorityFeePerGas=web3_connect.gwei_to_wei(math.ceil(gas_station["maxPriorityFee"])),
            )
        )
    
[/code]

このpythonを実行するとエラーになりました。

[code]

     "Incorrect argument count.  Expected '1'.  Got '2'"
    
[/code]

abiを取得すると、Versionクラスの分のみとなっているため、引数の数が一致しないということまではわかりました。

remixだとどのクラスをコンパイルするか指定できますが、py-solc-xでも同じように出来ないでしょうか？  
もしくはVersionクラスの書き方が良くないのか、どなたかご存じないでしょうか。


CC BY-SA 4.0
2022-09-02T03:50:57.400
90895
2022-09-07T06:00:34.730
2022-09-02T04:25:37.423
27721
27721
question
ethereum solidity
Smartcontractにて同じファイルに2つのクラスを持つSolidityをpy-solc-xでコンパイルするにはどうすればよいのでしょうか？


自己解決しました。

載せていないコードに問題というか考慮不足がありました。

[code]

        compiled_sol = compile_source_file(SOLC_VERSION, main_contract + ".sol")
        contract_id, contract_interface = compiled_sol.popitem()
        abi = contract_interface["abi"]
    
[/code]

というようにして、abiを取得していました。  
`compile_source_file`関数は独自で、内部では`py-solc-x.compile_source()`を実行しています。

複数のクラスがある場合、`len(compiled_sol)`で参照すると今回の場合、`2`となります。  
その結果、popitemでは最初の一つ目を取ってくることとなり、Versionクラスのabiを返しBaseクラスの取得が漏れてしまいました。

[code]

        main_contract = "Base"
        while True:
            contract_id, contract_interface = compiled_sol.popitem()
            if main_contract in contract_id:
                break
            if len(compiled_sol) <= 0:
                result = {
                    "error": "Compile Failed",
                }
                pprint.pprint(result)
                return result
    
[/code]

上記のようにループしてチェックするようにしました。


CC BY-SA 4.0
2022-09-07T06:00:34.730
90974
2022-09-07T06:00:34.730
27721
90895
answer