Kaleido vm处于只读模式

时间:2018-06-27 15:11:13

标签: ethereum kaleido

我已经在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。另外,当我访问节点的区块浏览器时,事务不会加载,而区块却会加载。

transactions not loading

对于这种只读模式我该怎么办?

2 个答案:

答案 0 :(得分:1)

moghadasian,

“处于只读模式的VM”是因为您正在使用call与Smart Contract方法进行交互。因此,它只是以只读模式调用您的方法。您可以使用它来调用查询数据合同的方法,而不必向链上提交交易。

[edit]-上面的建议通常对“处于只读模式的VM”很有帮助,但是如果您尝试使用python web3,则可能需要其他答案以及完整的工作示例:https://stackoverflow.com/a/51155413/4972840 [/ edit]

关于彼得,

答案 1 :(得分:1)

moghadasian

提交事务时,我无法重新创建“只读模式的VM”-成功运行。 但是,我必须做一些调查才能使web3 / python连接到Kaleido-因此,我添加了一个单独的答案来帮助其他尝试入门的人。

从Python web3配置对Kaleido的HTTPS身份验证

在我的Mac上,默认安装了web3的pip3,我发现用auth配置Python会话的唯一方法是使用$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

更新的示例,包括合同的部署

这是成功部署并报告Updated contract greeting: Nihao的python3。 您需要将HTTPProvider更改为节点的HTTPS RPC URL,但没有身份验证标头。

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"