ethereumkaleido

Kaleido vm in read-only mode


I've successfully deployed the following contract on Kaleido:

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 try to interact with the contract like so:


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

# 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) 
contract_interface = compiled_sol[':Greeter']

w3 = Web3(HTTPProvider("https://user:password@u0telyzine-u0od4ny83j-rpc.us-east-2.kaleido.io"))

# address from previous deployment
contract_address = Web3.toChecksumAddress("0x4c94e89d5ec3125339906109f143673f40868df2")

greeter = w3.eth.contract(
    address=contract_address,
    abi=contract_interface['abi'],
)

print('Default contract greeting: {}'.format(
    greeter.functions.greet().call()
))

# --- this hangs ---
print('Setting the greeting to Nihao...')
tx_hash = greeter.functions.setGreeting('Nihao').transact({ 'from': w3.eth.accounts[0], 'gas': 100000})

w3.eth.waitForTransactionReceipt(tx_hash)

print('Updated contract greeting: {}'.format(
    greeter.functions.greet().call()
))

reader = ConciseContract(greeter)
assert reader.greet() == "Nihao"

However, when I try to submit a transaction which calls setGreeting the transaction hangs. Viewing the Kaleido logs, I see VM in read-only mode. Mutating opcode prohibited. Also, when I visit the block explorer for my node, the transactions don't load while the blocks do.

transactions not loading

What can I do about this read only mode?


Solution

  • moghadasian

    I could not recreate your "VM in read-only mode" when submitting a transaction - that worked successfully. However, I had to do a bit of investigation to get web3/python connecting to Kaleido - so I'm adding a separate answer to help others trying to get going.

    Configuring HTTPS authentication to Kaleido from Python web3

    On my Mac, with a default pip3 installation of web3, I found the only way to configure the Python Session with auth was to use a $HOME/.netrc file such as:

    machine u0oaXXXXXX-u0c4XXXXXX-rpc.us-east-2.kaleido.io
    login u0d0bxXXXX
    password jA-pJdIrcRaIx7XXXXXXXXXXXXXXXXXXXXXXXXX
    

    Configure web3 for Geth/PoA

    My chain was using Geth/PoA, so I had to follow the instructions here, to install the required middleware: http://web3py.readthedocs.io/en/stable/middleware.html#geth-style-proof-of-authority

    Updated example including deployment of contract

    Here is the python3 that successfully deployed and reported Updated contract greeting: Nihao. You will need to change your HTTPProvider to the HTTPS RPC URL of your node, but without the authentication headers.

    from web3 import Web3
    from web3.providers import 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.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) 
    contract_interface = compiled_sol['<stdin>:Greeter']
    
    w3 = Web3(HTTPProvider("https://u0oaXXXXXX-u0c4XXXXXX-rpc.us-east-2.kaleido.io"))
    w3.middleware_stack.inject(geth_poa_middleware, layer=0)
    
    Greeter = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
    tx_hash = Greeter.constructor().transact({ 'from': w3.eth.accounts[0], 'gas': 1000000})
    tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    print('Deployed greeter contract: {}'.format(tx_receipt.contractAddress))
    
    # address from previous deployment
    contract_address = Web3.toChecksumAddress(tx_receipt.contractAddress)
    
    greeter = w3.eth.contract(
        address=contract_address,
        abi=contract_interface['abi'],
    )
    
    print('Default contract greeting: {}'.format(
        greeter.functions.greet().call()
    ))
    
    print('Setting the greeting to Nihao...')
    tx_hash = greeter.functions.setGreeting('Nihao').transact({ 'from': w3.eth.accounts[0], 'gas': 100000})
    
    w3.eth.waitForTransactionReceipt(tx_hash)
    
    print('Updated contract greeting: {}'.format(
        greeter.functions.greet().call()
    ))
    
    reader = ConciseContract(greeter)
    assert reader.greet() == "Nihao"