Kaleido 虚拟机处于只读模式

Kaleido vm in read-only mode

我已经在 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;
    }
}

我尝试像这样与合约交互:


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"

但是,当我尝试提交调用 setGreeting 的交易时,交易挂起。查看 Kaleido 日志,我看到 VM in read-only mode. Mutating opcode prohibited。此外,当我访问我的节点的区块浏览器时,交易不会在区块加载时加载。

对于这种只读模式我能做什么?

摩加达人,

"VM in read-only mode" 是因为您正在使用 call 与您的智能合约方法进行交互。所以它只是以只读模式调用你的方法。您可以使用它来调用查询数据的合约方法——无需向链提交交易。

[edit] - 以上建议通常对 "VM in read-only mode" 有帮助,但如果您正在尝试 python web3,您可能需要另一个答案以及完整的工作示例:[/编辑]

此致,彼得

摩加达人

提交交易时我无法重新创建您的 "VM in read-only mode" - 成功了。 但是,我必须做一些调查才能 web3/python 连接到 Kaleido - 所以我添加了一个单独的答案来帮助其他人尝试开始。

正在从 Python web3

配置到 Kaleido 的 HTTPS 身份验证

在我的 Mac 上,默认安装了 web3 的 pip3,我发现使用 auth 配置 Python Session 的唯一方法是使用 $HOME/.netrc文件如:

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

为 Geth/PoA

配置 web3

我的链正在使用 Geth/PoA,所以我必须按照此处的说明安装所需的中间件: http://web3py.readthedocs.io/en/stable/middleware.html#geth-style-proof-of-authority

更新示例包括合同部署

这里是 python3 成功部署并报告 Updated contract greeting: Nihao。 您需要将 HTTPProvider 更改为节点的 HTTPS RPC URL,但无需身份验证 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"