我已经成功地将合同部署到了Kaleido,但是我在弄清楚如何正确验证合同方面遇到了麻烦。这是部署合同的源代码,我已经验证了最后一个打印语句打印的地址出现在我的Kaleido区块链中:
from web3 import Web3 from web3.providers import HTTPProvider from solc import compile_source # 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) # Compiled source code contract_interface = compiled_sol[':Greeter'] w3 = Web3(HTTPProvider("https://XXXXX:YYYYY@ZZZZZZZ.kaleido.io")) contract_ = w3.eth.contract( abi=contract_interface['abi'], bytecode=contract_interface['bin']) # note: when interacting with kaleido, gasPrice MUST be 0 (I think because of the consensus algorithm I chose) # and it seems it doesn't matter what account this is sent from construct_txn = contract_.constructor().buildTransaction({ 'from': w3.eth.accounts[0], 'gas': 1728712, 'gasPrice': 0}) txn = w3.eth.sendTransaction(construct_txn) tx_receipt = w3.eth.getTransactionReceipt(txn) contract_address = tx_receipt['contractAddress'] print(contract_address)
当我尝试验证合同时,要求我提供源代码,合同名称,编译器版本以及是否使用了优化。
我将以下内容用作请求的源代码
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; } }
我使用Greeter
作为合同名称。 solc --version
返回Version: 0.4.24+commit.e67f0147.Darwin.appleclang
,我发现它是在5月16日提交的https://github.com/ethereum/solidity/search?q=e67f0147&type=Commits。
我尝试了以下所有组合来启用编译器版本+优化:{0.4.24,0.4.24-nightly.2018.5.16} x {已启用优化,已禁用优化},但这些组合均无效。当我尝试0.4.24-nightly.2018.5.16时出现以下错误,因为未启用编译器和优化。
The compiled result does not match the input creation bytecode located at 0x4c94e89d5ec3125339906109f143673f40868df2. Compilation failed: ["Warning: This is a pre-release compiler version, please do not use it in production.\n",":6:5: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use \"constructor(...) { ... }\" instead.\n function Greeter() {\n ^ (Relevant source part starts here and spans across multiple lines).\n",":6:5: Warning: No visibility specified. Defaulting to \"public\". \n function Greeter() {\n ^ (Relevant source part starts here and spans across multiple lines).\n",":14:5: Warning: No visibility specified. Defaulting to \"public\". \n function greet() constant returns (string) {\n ^ (Relevant source part starts here and spans across multiple lines).\n"] .
答案 0 :(得分:1)
您不需要编译器参数即可验证合同。只有在极少数情况下,您才需要了解它们。我目前使用0.4.21编译器,并且能够仅使用合同Solidity源代码来验证我的合同。
我可能建议您指定您在合同实用程序中使用的特定编译器,而不是^ 0.4.0。
当我尝试进行验证时,我也在使用Geth PoA
环境,并且必须对您的代码进行一些修改才能使其正常工作。您正在使用Quorum环境吗?哪个协议?
这是我的代码摘自自述文件中的“快速入门”示例:
import json
import web3
from web3 import Web3, 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.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() public returns (string) {
return greeting;
}
}
'''
compiled_sol = compile_source(contract_source_code) # Compiled source code
contract_interface = compiled_sol['<stdin>:Greeter']
# web3.py instance
w3 = Web3(HTTPProvider("https://YYY:ZZZ@XXXXXX.us-east-2.kaleido.io"))
w3.middleware_stack.inject(geth_poa_middleware, layer=0)
# set pre-funded account as sender
w3.eth.defaultAccount = w3.eth.accounts[0]
# Instantiate and deploy contract
Greeter = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
# Submit the transaction that deploys the contract
tx_hash = Greeter.constructor().transact()
# Wait for the transaction to be mined, and get the transaction receipt
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
print(tx_receipt.contractAddress)
# Create the contract instance with the newly-deployed address
greeter = w3.eth.contract(
address=tx_receipt.contractAddress,
abi=contract_interface['abi'],
)
# Display the default greeting from the contract
print('Default contract greeting: {}'.format(
greeter.functions.greet().call()
))
print('Setting the greeting to Nihao...')
tx_hash = greeter.functions.setGreeting('Nihao').transact()
# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)
# Display the new greeting value
print('Updated contract greeting: {}'.format(
greeter.functions.greet().call()
))
# When issuing a lot of reads, try this more concise reader:
reader = ConciseContract(greeter)
assert reader.greet() == "Nihao"
如果您确实需要知道如何查找编译时参数,则通常将它们作为kwargs
提供给编译函数。这是可以发挥作用的源代码行:https://github.com/ethereum/py-solc/blob/c595d84d9f0ef5f5da0a5d79e7d5fcabecfe5f06/solc/main.py#L106