Kaleido vm в режиме только для чтения - PullRequest
0 голосов
/ 27 июня 2018

Я успешно развернул следующий контракт на 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 голосов
/ 03 июля 2018

moghadasian

Я не мог воссоздать вашу "ВМ в режиме только для чтения" при отправке транзакции - она ​​работала успешно. Однако мне пришлось провести небольшое исследование, чтобы подключить web3 / python к Kaleido - поэтому я добавляю отдельный ответ, чтобы помочь другим, пытающимся начать работу.

Настройка аутентификации HTTPS для Kaleido из Python web3

На моем Mac с установленной по умолчанию pip3 web3 я обнаружил, что единственный способ настроить Python Session с аутентификацией - это использовать файл $HOME/.netrc, такой как:

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

Настройка web3 для Geth / PoA

В моей цепочке использовался Geth / PoA, поэтому мне пришлось следовать приведенным здесь инструкциям, чтобы установить необходимое промежуточное ПО: http://web3py.readthedocs.io/en/stable/middleware.html#geth-style-proof-of-authority

Обновленный пример, включающий развертывание контракта

Вот python3, который успешно развернут и сообщил Updated contract greeting: Nihao. Вам нужно будет изменить HTTPProvider на URL-адрес HTTPS RPC вашего узла, но без заголовков аутентификации.

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"
0 голосов
/ 28 июня 2018

moghadasian,

«Виртуальная машина в режиме только для чтения» связана с тем, что вы используете call для взаимодействия с методом Smart Contract. Так что это просто вызов вашего метода в режиме только для чтения. Это можно использовать для вызова методов в контрактах, которые запрашивают данные, без необходимости отправки транзакции в цепочку.

[править] - приведенный выше совет, как правило, полезен для "ВМ в режиме только для чтения", но если вы пробуете python web3, вам, возможно, понадобится другой ответ с полным рабочим примером: https://stackoverflow.com/a/51155413/4972840 [/ edit]

С уважением, Питер

...