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.
What can I do about this read only mode?
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.
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
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
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"