【发布时间】:2018-10-16 02:07:44
【问题描述】:
我正在玩弄以太坊和 python,但我遇到了一些我无法理解的奇怪行为。在使用 python w3 客户端调用合同函数时,我无法理解返回值是如何工作的。这是一个最小的例子,它以几种不同的方式让我感到困惑:
合同:
编译指示 ^0.4.0; 合同测试{ 功能测试(){ } 函数 return_true() 公共返回 (bool) { 返回真; } 函数 return_address() 公共返回 (地址) { 返回0x11111111111111111111111111111111111111; } }Python 单元测试代码
从 web3 导入 Web3,EthereumTesterProvider 从 solc 导入 compile_source 从 web3.contract 导入 ConciseContract 导入单元测试 导入操作系统 def get_contract_source(文件名): 使用 open(file_name) 作为 f: 返回 f.read() 类TestContract(unittest.TestCase): CONTRACT_FILE_PATH = "test.sol" DEFAULT_PROPOSAL_ADDRESS = "0x111111111111111111111111111111111111111" 默认设置(自我): # 使用 MIT 许可证从 https://github.com/ethereum/web3.py/tree/1802e0f6c7871d921e6c5f6e43db6bf2ef06d8d1 复制 # 稍作修改以使用此单元测试 contract_source_code = get_contract_source(self.CONTRACT_FILE_PATH) compiled_sol = compile_source(contract_source_code) # 编译好的源代码 contract_interface =compiled_sol[':test'] # web3.py 实例 self.w3 = Web3(EthereumTesterProvider()) # 实例化和部署合约 self.contract = self.w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin']) # 从已部署的合约中获取交易哈希 tx_hash = self.contract.constructor().transact({'from': self.w3.eth.accounts[0]}) # 获取 tx 收据以获取合约地址 tx_receipt = self.w3.eth.getTransactionReceipt(tx_hash) self.contract_address = tx_receipt['contractAddress'] # 简洁模式下的合约实例 abi = contract_interface['abi'] self.contract_instance = self.w3.eth.contract(address=self.contract_address, abi=abi, ContractFactoryClass=ConciseContract) def test_return_true_with_gas(self): # HexBytes 失败('0xd302f7841b5d7c1b6dcff6fca0cd039666dbd0cba6e8827e72edb4d06bbab38f') != True self.assertEqual(True, self.contract_instance.return_true(transact={"from": self.w3.eth.accounts[0]})) def test_return_true_no_gas(self): # 次通过 self.assertEqual(True, self.contract_instance.return_true()) def test_return_address(self): # 失败并出现 AssertionError: '0x1111111111111111111111111111111111111111' != '0x011111111111111111111111111111111111111' self.assertEqual(self.DEFAULT_PROPOSAL_ADDRESS, self.contract_instance.return_address())我有三种方法对合约中的功能进行测试。在其中一个中,返回非True 值,而是返回HexBytes。在另一种情况下,合约函数返回一个地址常量,但 python 看到的值与预期的不同。在另一种情况下,我在没有气体的情况下调用 return_true 合约函数,python 可以看到 True 常量。
- 为什么用
transact={"from": self.w3.eth.accounts[0]}调用return_true会导致函数的返回值为HexBytes(...)? - 为什么
return_address返回的地址与我预期的不同?
我认为我对气体如何影响函数调用存在某种根本性的误解。
【问题讨论】:
-
交易没有返回值。如果您发送交易,则结果是交易哈希。然后您可以等待交易被挖掘并查看结果,但没有返回值可用。如果您改为
call方法,则在本地计算结果而不向网络的其余部分发送事务,并在响应中将函数的返回值发回给您。 -
啊,我明白了。谢谢!
标签: python ethereum solidity web3