HydraChain / hydrachain

Permissioned Distributed Ledger based on Ethereum
MIT License
358 stars 105 forks source link

Interaction with contract from the console silently fails #66

Open 4gn3s opened 8 years ago

4gn3s commented 8 years ago

Hi. I am following the tutorial from here in Hydrachain to create a sample contract and interact with it. I run three separate Hydrachain nodes using the 'rundummy' syntax. The transactions are created and added to blocks successfully. However, when registering a new name in contract, a new event is thrown, which should be visible in logs, and they are empty. Later, when trying to resolve the name, I also get an empty string. Is there any reason why this would not work in Hydrachain?

This is my console output:

In [1]: code ="""
   ...:    ....: contract NameReg  {
   ...:    ....:        event AddressRegistered(bytes32 indexed name, address indexed account);
   ...:    ....:        mapping (address => bytes32) toName;
   ...:    ....: 
   ...:    ....:        function register(bytes32 name) {
   ...:    ....:                toName[msg.sender] = name;
   ...:    ....:                AddressRegistered(name, msg.sender);
   ...:    ....:        }
   ...:    ....: 
   ...:    ....:        function resolve(address addr) constant returns (bytes32 name) {
   ...:    ....:                return toName[addr];
   ...:    ....:        }
   ...:    ....: }
   ...:    ....: """

In [2]: evm_code = solidity.compile(code)

In [3]: abi = solidity.mk_full_signature(code)

In [4]: tx = eth.transact(to='', data=evm_code, startgas=500000)

In [5]: eth.find_transaction(tx)
Out[5]: {'block': <Block(#23 66ca545b)>, 'index': 0, 'tx': <Transaction(d4b3)>}

In [6]: namereg = eth.new_contract(abi, tx.creates)

In [7]: tx = namereg.register('alice')

In [8]: eth.find_transaction(tx)
Out[8]: {'block': <Block(#24 d0dbdcdd)>, 'index': 0, 'tx': <Transaction(f659)>}

In [9]: eth.latest
Out[9]: <CachedBlock(#24 d0dbdcdd)>

In [10]: eth.latest.logs
Out[10]: []

In [11]: namereg.resolve(eth.coinbase)
Out[11]: ''

The more detailed logs are here:

DEBUG:eth.chain.tx deserialized tx tx=98f0ba96
DEBUG:eth.block created cached block blk=<CachedBlock(#19 f089738b)>
DEBUG:eth.chain.tx deserialized tx tx=99a5dd96
DEBUG:eth.chain.tx deserialized tx tx=99a5dd96
DEBUG:eth.block created cached block blk=<CachedBlock(#18 d07cb571)>
DEBUG:eth.chain.tx deserialized tx tx=beb36fbe
DEBUG:eth.chain.tx deserialized tx tx=beb36fbe
DEBUG:eth.block created cached block blk=<CachedBlock(#17 3e4bcde2)>
DEBUG:eth.chain.tx deserialized tx tx=d4b3705f
DEBUG:eth.chainservice new head cbs num=0
INFO:hdc.chainservice new head head=<CachedBlock(#23 66ca545b)>
DEBUG:eth.chain.tx deserialized tx tx=d4b3705f
DEBUG:eth.chain.tx deserialized tx tx=d4b3705f
DEBUG:eth.chain.tx deserialized tx tx=d4b3705f
DEBUG:eth.chain.tx deserialized tx tx=a2628d1f
INFO:accounts signing tx account=<Account(address=8ed66d0dd4b88fb097a3a3c8c10175b8cadb1c66, id=None)> tx=<Transaction(a262)>
DEBUG:eth.chainservice add_transaction locked=True tx=<Transaction(f659)>
DEBUG:eth.chainservice valid tx, broadcasting 
DEBUG:eth.chain add tx on=<Block(#24 c414f120)> num_txs=0 tx=<Transaction(f659)>
INFO:app {'ACCOUNT_INITIAL_NONCE': 1048576, 'HOMESTEAD_FORK_BLKNUM': 494000, 'BLKLIM_FACTOR_DEN': 2, 'GENESIS_EXTRA_DATA': '', 'BLOCK_REWARD': 5000000000000000000, 'GENESIS_INITIAL_ALLOC': {'0000000000000000000000000000000000000001': {'balance': '1'}, '0000000000000000000000000000000000000002': {'balance': '1'}, '0000000000000000000000000000000000000003': {'balance': '1'}, '0000000000000000000000000000000000000004': {'balance': '1'}, '102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c': {'balance': '1606938044258990275541962092341162602522202993782792835301376'}}, 'BLOCK_DIFF_FACTOR': 2048, 'GASLIMIT_ADJMAX_FACTOR': 1024, 'EXPDIFF_PERIOD': 100000, 'NEPHEW_REWARD': 156250000000000000, 'MAX_UNCLES': 2, 'MAX_UNCLE_DEPTH': 6, 'GENESIS_TIMESTAMP': 0, 'MIN_GAS_LIMIT': 5000, 'GENESIS_DIFFICULTY': 131072, 'BLKLIM_FACTOR_NOM': 3, 'UNCLE_DEPTH_PENALTY_FACTOR': 8, 'DIFF_ADJUSTMENT_CUTOFF': 13, 'GENESIS_PREVHASH': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'MAX_EXTRADATA_LENGTH': 32, 'GENESIS_NONCE': '\x00\x00morden', 'GENESIS_MIXHASH': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00duralexsedlex', 'GASLIMIT_EMA_FACTOR': 1024, 'GENESIS_GAS_LIMIT': 3141592, 'POW_EPOCH_LENGTH': 30000, 'hdc': {'user_registry_contract_address': ''}, 'EXPDIFF_FREE_PERIODS': 2, 'GENESIS_COINBASE': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'MIN_DIFF': 131072, 'HOMESTEAD_DIFF_ADJUSTMENT_CUTOFF': 10} 
DEBUG:eth.pb.tx TX NEW tx_dict={'nonce': 1048589, 'hash': 'f659010308408aec589a201b4498f7305bc03ba98a884829db145dc6efa90fbc', 'sender': '8ed66d0dd4b88fb097a3a3c8c10175b8cadb1c66', 'startgas': 25000, 'value': 0, 'to': '774ebcc8baf22fd42a806d341e6fde43aba07963', 's': 5188698760495285028116380571892894587053416723393116677650966853211984847297L, 'r': 46919339581143003016320872801387508223771591416802274395589386353228808425567L, 'v': 28, 'data': 'e1fa8e84616c696365000000000000000000000000000000000000000000000000000000', 'gasprice': 60000000000}
DEBUG:eth.pb.tx _res_ data=[] result=1 gas_remained=3280
DEBUG:eth.pb.tx TX APPLIED data=[] result=1 gas_remained=3280
DEBUG:eth.pb.tx TX SUCCESS data=[]
DEBUG:eth.chain valid tx 
DEBUG:eth.chain tx applied result=
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chainservice add_transaction locked=True tx=<Transaction(f659)>
DEBUG:eth.chainservice discarding known tx 
DEBUG:eth.chainservice add_transaction locked=True tx=<Transaction(f659)>
DEBUG:eth.chainservice discarding known tx 
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx recovering sender 
INFO:app {'ACCOUNT_INITIAL_NONCE': 1048576, 'HOMESTEAD_FORK_BLKNUM': 494000, 'BLKLIM_FACTOR_DEN': 2, 'GENESIS_EXTRA_DATA': '', 'BLOCK_REWARD': 5000000000000000000, 'GENESIS_INITIAL_ALLOC': {'0000000000000000000000000000000000000001': {'balance': '1'}, '0000000000000000000000000000000000000002': {'balance': '1'}, '0000000000000000000000000000000000000003': {'balance': '1'}, '0000000000000000000000000000000000000004': {'balance': '1'}, '102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c': {'balance': '1606938044258990275541962092341162602522202993782792835301376'}}, 'BLOCK_DIFF_FACTOR': 2048, 'GASLIMIT_ADJMAX_FACTOR': 1024, 'EXPDIFF_PERIOD': 100000, 'NEPHEW_REWARD': 156250000000000000, 'MAX_UNCLES': 2, 'MAX_UNCLE_DEPTH': 6, 'GENESIS_TIMESTAMP': 0, 'MIN_GAS_LIMIT': 5000, 'GENESIS_DIFFICULTY': 131072, 'BLKLIM_FACTOR_NOM': 3, 'UNCLE_DEPTH_PENALTY_FACTOR': 8, 'DIFF_ADJUSTMENT_CUTOFF': 13, 'GENESIS_PREVHASH': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'MAX_EXTRADATA_LENGTH': 32, 'GENESIS_NONCE': '\x00\x00morden', 'GENESIS_MIXHASH': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00duralexsedlex', 'GASLIMIT_EMA_FACTOR': 1024, 'GENESIS_GAS_LIMIT': 3141592, 'POW_EPOCH_LENGTH': 30000, 'hdc': {'user_registry_contract_address': ''}, 'EXPDIFF_FREE_PERIODS': 2, 'GENESIS_COINBASE': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'MIN_DIFF': 131072, 'HOMESTEAD_DIFF_ADJUSTMENT_CUTOFF': 10} 
DEBUG:eth.pb.tx TX NEW tx_dict={'nonce': 1048589, 'hash': 'f659010308408aec589a201b4498f7305bc03ba98a884829db145dc6efa90fbc', 'sender': '8ed66d0dd4b88fb097a3a3c8c10175b8cadb1c66', 'startgas': 25000, 'value': 0, 'to': '774ebcc8baf22fd42a806d341e6fde43aba07963', 's': 5188698760495285028116380571892894587053416723393116677650966853211984847297L, 'r': 46919339581143003016320872801387508223771591416802274395589386353228808425567L, 'v': 28, 'data': 'e1fa8e84616c696365000000000000000000000000000000000000000000000000000000', 'gasprice': 60000000000}
DEBUG:eth.pb.tx _res_ data=[] result=1 gas_remained=3280
DEBUG:eth.pb.tx TX APPLIED data=[] result=1 gas_remained=3280
DEBUG:eth.pb.tx TX SUCCESS data=[]
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain new head block_hash=<Block(#24 d0dbdcdd)> num_tx=1
DEBUG:eth.chain updating head 
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.block created cached block blk=<CachedBlock(#24 d0dbdcdd)>
DEBUG:eth.chain set new head head=<CachedBlock(#24 d0dbdcdd)>
DEBUG:eth.chain updating head candidate head=<CachedBlock(#24 d0dbdcdd)>
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.block created cached block blk=<CachedBlock(#24 d0dbdcdd)>
DEBUG:eth.chain.tx deserialized tx tx=d4b3705f
DEBUG:eth.chain.tx deserialized tx tx=d4b3705f
DEBUG:eth.block created cached block blk=<CachedBlock(#23 66ca545b)>
DEBUG:eth.chain.tx deserialized tx tx=5b1fef33
DEBUG:eth.chain.tx deserialized tx tx=5b1fef33
DEBUG:eth.block created cached block blk=<CachedBlock(#22 79095c4d)>
DEBUG:eth.chain.tx deserialized tx tx=c58aceee
DEBUG:eth.chain.tx deserialized tx tx=c58aceee
DEBUG:eth.block created cached block blk=<CachedBlock(#21 4a65a9b6)>
DEBUG:eth.chain.tx deserialized tx tx=a03fc71a
DEBUG:eth.chain.tx deserialized tx tx=a03fc71a
DEBUG:eth.block created cached block blk=<CachedBlock(#20 7b5f93a6)>
DEBUG:eth.chain.tx deserialized tx tx=98f0ba96
DEBUG:eth.chain.tx deserialized tx tx=98f0ba96
DEBUG:eth.block created cached block blk=<CachedBlock(#19 f089738b)>
DEBUG:eth.chain.tx deserialized tx tx=99a5dd96
DEBUG:eth.chain.tx deserialized tx tx=99a5dd96
DEBUG:eth.block created cached block blk=<CachedBlock(#18 d07cb571)>
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chainservice new head cbs num=0
INFO:hdc.chainservice new head head=<CachedBlock(#24 d0dbdcdd)>
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=f6590103
DEBUG:eth.chain.tx deserialized tx tx=3b27ef21
INFO:app {'ACCOUNT_INITIAL_NONCE': 1048576, 'HOMESTEAD_FORK_BLKNUM': 494000, 'BLKLIM_FACTOR_DEN': 2, 'GENESIS_EXTRA_DATA': '', 'BLOCK_REWARD': 5000000000000000000, 'GENESIS_INITIAL_ALLOC': {'0000000000000000000000000000000000000001': {'balance': '1'}, '0000000000000000000000000000000000000002': {'balance': '1'}, '0000000000000000000000000000000000000003': {'balance': '1'}, '0000000000000000000000000000000000000004': {'balance': '1'}, '102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c': {'balance': '1606938044258990275541962092341162602522202993782792835301376'}}, 'BLOCK_DIFF_FACTOR': 2048, 'GASLIMIT_ADJMAX_FACTOR': 1024, 'EXPDIFF_PERIOD': 100000, 'NEPHEW_REWARD': 156250000000000000, 'MAX_UNCLES': 2, 'MAX_UNCLE_DEPTH': 6, 'GENESIS_TIMESTAMP': 0, 'MIN_GAS_LIMIT': 5000, 'GENESIS_DIFFICULTY': 131072, 'BLKLIM_FACTOR_NOM': 3, 'UNCLE_DEPTH_PENALTY_FACTOR': 8, 'DIFF_ADJUSTMENT_CUTOFF': 13, 'GENESIS_PREVHASH': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'MAX_EXTRADATA_LENGTH': 32, 'GENESIS_NONCE': '\x00\x00morden', 'GENESIS_MIXHASH': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00duralexsedlex', 'GASLIMIT_EMA_FACTOR': 1024, 'GENESIS_GAS_LIMIT': 3141592, 'POW_EPOCH_LENGTH': 30000, 'hdc': {'user_registry_contract_address': ''}, 'EXPDIFF_FREE_PERIODS': 2, 'GENESIS_COINBASE': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'MIN_DIFF': 131072, 'HOMESTEAD_DIFF_ADJUSTMENT_CUTOFF': 10} 
DEBUG:eth.pb.tx TX NEW tx_dict={'nonce': 1048590, 'hash': '3b27ef21d0432c79ef579eb3a8e12c25ce924340e0ce114489025e94f3491f46', 'sender': '8ed66d0dd4b88fb097a3a3c8c10175b8cadb1c66', 'startgas': 25000, 'value': 0, 'to': '774ebcc8baf22fd42a806d341e6fde43aba07963', 's': 0, 'r': 0, 'v': 0, 'data': '55ea6c470000000000000000000000008ed66d0dd4b88fb097a3a3c8c10175b8cadb1c66', 'gasprice': 60000000000}
DEBUG:eth.pb.tx _res_ data=[] result=1 gas_remained=2320
DEBUG:eth.pb.tx TX APPLIED data=[] result=1 gas_remained=2320
DEBUG:eth.pb.tx TX SUCCESS data=[]

I have also written a simple test with tester, doing basically the same thing:

import unittest

from ethereum import tester
from pyethapp.jsonrpc import data_decoder

class TestSolidityInteraction(unittest.TestCase):

    CONTRACT_CODE = """
    contract NameReg  {
           event AddressRegistered(bytes32 indexed name, address indexed account);
           mapping (address => bytes32) toName;

           function register(bytes32 name) {
                   toName[msg.sender] = name;
                   AddressRegistered(name, msg.sender);
           }

           function resolve(address addr) constant returns (bytes32 name) {
                   return toName[addr];
           }
    }
    """

    @classmethod
    def setup_class(cls):
        cls.state = tester.state()
        cls.owner = tester.k0
        cls.owner_account = tester.a0
        cls.contract = cls.state.abi_contract(cls.CONTRACT_CODE, language='solidity', sender=cls.owner)
        cls.snapshot = cls.state.snapshot()

    def setUp(self):
        self.state.revert(self.snapshot)

    def test_write_read(self):
        logs = []
        self.state.block.log_listeners.append(lambda x: logs.append(self.contract._translator.listen(x)))
        name = 'alice'
        self.contract.register(name)
        self.assertEqual(len(logs), 1)
        self.assertDictEqual(logs[0], {"_event_type": b"AddressRegistered", "account": tester.a0.encode('hex'), "name": name+"\x00"*(32-len(name))})
        self.assertIsNotNone(self.contract.resolve(self.owner_account))

and the test passes, so I guess this is not a problem with my solidity compiler (I'm using Version: 0.3.2-0/RelWithDebInfo-Linux/g++/Interpreter).

4gn3s commented 8 years ago

After some more testing, I was able to confirm that the code did not get deployed at all. I haven't, however, received any error about this. This is some more logs about the transaction:

In [1]: code ="""
   ...:    ....: contract NameReg  {
   ...:    ....:        event AddressRegistered(bytes32 indexed name, address indexed account);
   ...:    ....:        mapping (address => bytes32) toName;
   ...:    ....: 
   ...:    ....:        function register(bytes32 name) {
   ...:    ....:                toName[msg.sender] = name;
   ...:    ....:                AddressRegistered(name, msg.sender);
   ...:    ....:        }
   ...:    ....: 
   ...:    ....:        function resolve(address addr) constant returns (bytes32 name) {
   ...:    ....:                return toName[addr];
   ...:    ....:        }
   ...:    ....: }
   ...:    ....: """

In [2]: evm_code = solidity.compile(code)

In [3]: abi = solidity.mk_full_signature(code)

In [4]: tx = eth.transact(to='', data=evm_code, startgas=500000)

In [5]: tx.sender
Out[5]: '\x8e\xd6m\r\xd4\xb8\x8f\xb0\x97\xa3\xa3\xc8\xc1\x01u\xb8\xca\xdb\x1cf'

In [6]: eth.coinbase
Out[6]: '\x8e\xd6m\r\xd4\xb8\x8f\xb0\x97\xa3\xa3\xc8\xc1\x01u\xb8\xca\xdb\x1cf'

In [7]: eth.find_transaction(tx)
Out[7]: {'block': <Block(#30 3476785d)>, 'index': 0, 'tx': <Transaction(026c)>}

In [8]: eth.latest.get_code(tx.creates)
Out[8]: ''

In [9]: tx
Out[9]: <Transaction(026c)>

In [10]: tx.to_dict()
Out[10]: 
{'data': '```@R`\xab\x80`\x10`\x009`\x00\xf3```@R`\xe0`\x02\n`\x005\x04cU\xealG\x81\x14`$W\x80c\xe1\xfa\x8e\x84\x14`TW[\x00[s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff`\x045\x16`\x00\x90\x81R` \x81\x81R`@\x90\x91 T``\x90\x81R\xf3[`"`\x045s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff3\x16`\x00\x81\x81R` \x81\x90R`@\x81 \x83\x90U\x82\x90\x7f,\xdav:\x9dz\xe9$\x1f"\xe2!\x94\x7fe\xe3\x1e|\xf5\x8dy\xff\x18\xe3\xba\xddr\xac\xf4\xbe\x14\x89\x90``\xa3PV',
 'gasprice': 60000000000,
 'hash': '026c7a1e6551c81b390d6418034c389ed70f4f33e529d8c0c6f12c8cbc29d68a',
 'nonce': 1048595,
 'r': 27658781706602874032610195404402144102381924050538974420397862279255605044700L,
 's': 46254478970772610353317232515709069812327479835241987339329102033936505301870L,
 'sender': '\x8e\xd6m\r\xd4\xb8\x8f\xb0\x97\xa3\xa3\xc8\xc1\x01u\xb8\xca\xdb\x1cf',
 'startgas': 500000,
 'to': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
 'v': 28,
 'value': 0}

In [11]: tx.creates
Out[11]: '\xf5\xa1W]\xfd\x8d\x98\x1a\xb3U\x1b]\x1aI\xdd\x1bO\x85\x991'