1
votes

I've successfully deployed my contract to Kaleido but I'm having trouble figuring out how to correctly verify it. Here is the source code deploys the contract and I've verified the the address printed by the last print statement appears in my Kaleido blockchain:

from web3 import Web3
from web3.providers import HTTPProvider
from solc import compile_source

# Solidity source code
contract_source_code = '''
pragma solidity ^0.4.0;

contract Greeter {
    string public greeting;

    function Greeter() {
        greeting = 'Hello';
    }

    function setGreeting(string _greeting) public {
        greeting = _greeting;
    }

    function greet() constant returns (string) {
        return greeting;
    }
}
'''

compiled_sol = compile_source(contract_source_code) # Compiled source code
contract_interface = compiled_sol[':Greeter']

w3 = Web3(HTTPProvider("https://XXXXX:[email protected]"))

contract_ = w3.eth.contract(
    abi=contract_interface['abi'],
    bytecode=contract_interface['bin'])

# note: when interacting with kaleido, gasPrice MUST be 0 (I think because of the consensus algorithm I chose)
# and it seems it doesn't matter what account this is sent from
construct_txn = contract_.constructor().buildTransaction({
    'from': w3.eth.accounts[0],
    'gas': 1728712,
    'gasPrice': 0})
txn = w3.eth.sendTransaction(construct_txn)

tx_receipt = w3.eth.getTransactionReceipt(txn)
contract_address = tx_receipt['contractAddress']
print(contract_address)

When I try to verify my contract, I'm asked to provide the source code, the contract name, a compiler version and whether optimization was used.

I use the following for the requested source code

pragma solidity ^0.4.0;

contract Greeter {
    string public greeting;

    function Greeter() {
        greeting = 'Hello';
    }

    function setGreeting(string _greeting) public {
        greeting = _greeting;
    }

    function greet() constant returns (string) {
        return greeting;
    }
}

I use Greeter as the contract name. solc --version returns Version: 0.4.24+commit.e67f0147.Darwin.appleclang which I found was committed on May 16: https://github.com/ethereum/solidity/search?q=e67f0147&type=Commits.

I've tried all of the following combinations for compiler version + optimization enabled: {0.4.24, 0.4.24-nightly.2018.5.16} x {optimization enabled, optimization disabled} and none of these combinations worked. I get the following error when I try 0.4.24-nightly.2018.5.16 as the compiler and optimization not enabled.:

The compiled result does not match the input creation bytecode located at 0x4c94e89d5ec3125339906109f143673f40868df2.

 Compilation failed: ["Warning: This is a pre-release compiler version, please do not use it in production.\n",":6:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use \"constructor(...) { ... }\" instead.\n function Greeter() {\n ^ (Relevant source part starts here and spans across multiple lines).\n",":6:5: Warning: No visibility specified. Defaulting to \"public\". \n function Greeter() {\n ^ (Relevant source part starts here and spans across multiple lines).\n",":14:5: Warning: No visibility specified. Defaulting to \"public\". \n function greet() constant returns (string) {\n ^ (Relevant source part starts here and spans across multiple lines).\n"] .
1
Change your pragma in your code to 0.4.24 and select the non-nightly build.Adam Kipnis
Still no luck. I changed my pragma to be pragma solidity ^0.4.24; and I tried verifying with optimization both enabled and disabled and both times I was rejected.Paymahn Moghadasian

1 Answers

1
votes

You should not need compiler parameters in order to verify the contract. Only in rare occasions will you need to know them. I currently use 0.4.21 compiler and was able to verify my contract just with the contract Solidity source code.

I might suggest specifying the specific compiler you are using in your contract pragma, instead of ^0.4.0.

I was also using a Geth PoA environment when I attempted to verify, and had to make a few modifications to your code in order to get this to work. Are you using a Quorum environment? Which protocol?

Here is my code taken from the Quickstart example in the README:

import json
import web3

from web3 import Web3, HTTPProvider
from solc import compile_source
from web3.contract import ConciseContract
from web3.middleware import geth_poa_middleware

# Solidity source code
contract_source_code = '''
pragma solidity ^0.4.21;

contract Greeter {
    string public greeting;

    function Greeter() public {
        greeting = 'Hello';
    }

    function setGreeting(string _greeting) public {
        greeting = _greeting;
    }

    function greet() public returns (string) {
        return greeting;
    }
}
'''

compiled_sol = compile_source(contract_source_code) # Compiled source code
contract_interface = compiled_sol['<stdin>:Greeter']

# web3.py instance
w3 = Web3(HTTPProvider("https://YYY:[email protected]"))
w3.middleware_stack.inject(geth_poa_middleware, layer=0)

# set pre-funded account as sender
w3.eth.defaultAccount = w3.eth.accounts[0]

# Instantiate and deploy contract
Greeter = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])

# Submit the transaction that deploys the contract
tx_hash = Greeter.constructor().transact()

# Wait for the transaction to be mined, and get the transaction receipt
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
print(tx_receipt.contractAddress)
# Create the contract instance with the newly-deployed address
greeter = w3.eth.contract(
    address=tx_receipt.contractAddress,
    abi=contract_interface['abi'],
)

# Display the default greeting from the contract
print('Default contract greeting: {}'.format(
    greeter.functions.greet().call()
))

print('Setting the greeting to Nihao...')
tx_hash = greeter.functions.setGreeting('Nihao').transact()
# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)


# Display the new greeting value
print('Updated contract greeting: {}'.format(
    greeter.functions.greet().call()
))

# When issuing a lot of reads, try this more concise reader:
reader = ConciseContract(greeter)
assert reader.greet() == "Nihao"

If you really need to know how to find the compile time arguments, they are typically provided as kwargs to the compile functions. Here's the source line that would do the magic: https://github.com/ethereum/py-solc/blob/c595d84d9f0ef5f5da0a5d79e7d5fcabecfe5f06/solc/main.py#L106