For a project I'm working on I want to be able to create smart contracts and transactions from Python. There are several ways to do this, and pyethereum with pyethapp is one of the ways. And since Python is awesome, why not chose a fully Python based solution?
Pyethereum is the Python core library for Ethereum. To be honest, I'm not sure what this means and the README isn't very clear either. I assume it provides the basic classes and routines for interacting with Ethereum, but it's unclear if it's capable by itself to download a blockchain and what API it provides.
Pyethapp is a "python based client implementing the Ethereum cryptoeconomic state machine", Since it leverages Pyethereum and pydevp2p for p2p networking, I assume that means that by itself Pyethereum won't download the blockchain. So Pyethapp is probably a good choice to start hacking with Python and Ethereum.
And then there's Serpent. It's a Python-like language for writing smart contracts. General advise seems to be though to use Solidity in stead since it's the most mature so that's what I'll stick to, even with pyethereum.
Installing and using pyethapp
Installing pyethapp is pretty simple. Just pip install it in a (python2.7) virtualenv. You may need some additional tooling/libraries, I already had those installed.
After installing I wanted to connect pyethapp to the testnet because I already have some testing data / ether there, and the download should be much faster than the production network. You can do this by invoking pyethapp as follows
$ pyethapp --profile morden --data-dir ../state run
Where, in my case, ../state points to a place to store the blockchain data.
Pyethapp will look for peers to connect to and while doing this it will spit out confusing warnings. I've learned that these can be ignored, eventually it will start fetching blocks:
INFO:p2p.peer received hello client_version=Geth/Node1/v1.3.5/linux/go1.5.1 version=4 capabilities=(('eth', 63), ('eth', 62), ('eth', 61)) WARNING:eth.chainservice invalid network id remote_network_id=1529417 expected_network_id=2 WARNING:protocol protocol exception, stopping error=wrong network_id INFO:p2p.peer received hello client_version=Geth/v1.4.3-stable/linux/go1.5.1 version=4 capabilities=(('eth', 63), ('eth', 62), ('eth', 61)) WARNING:eth.chainservice invalid network id remote_network_id=1 expected_network_id=2
While downloading you can hit ^C and press enter. It will bring you to an interactive (ipython) shell where you can interact with the blockchain. E.g. look at the latest block, transactions, create contracts, and so on.
However, I know from the blockchain downloaded by geth that the testnet chain is about 1.2GB (on disk) right now. And pyethapp was downloading data awfully slow. It took a couple of hours before it downloaded about 600MB after which it crashed:
INFO:eth.chainservice added txs=66 gas_used=2611847 block=<Block(#173521 539c1e93)> INFO:eth.chainservice added txs=12 gas_used=674968 block=<Block(#173522 6e252728)> Traceback (most recent call last): File " (...) ethereum/pyethapp-pip/local/lib/python2.7/site-packages/gevent/greenlet.py", line 534, in run result = self._run(*self.args, **self.kwargs) File " (...) ethereum/pyethapp-pip/local/lib/python2.7/site-packages/pyethapp/eth_service.py", line 277, in _add_blocks except processblock.InvalidTransaction as e: AttributeError: 'module' object has no attribute 'InvalidTransaction' >> failed with AttributeError
So my guess is pyethereum / pyethapp can't handle a certain transaction (though I assume it's valid) and crashes while handling the generated exception.
I've retried this with both the released version if pyethapp (1.2.3) and a build from github (master branch), same problem (with blockchain data cleared between tests). I've reported an issue for this and I am curious to see what I did wrong :)
The interactive console tells me this is a block from december 2015.
In : time.ctime(eth.latest.header.timestamp)
Out : 'Sun Dec 20 18:39:17 2015'
This is where my pyethereum/pyethapp adventure stops for now. If I would have been able to download the testnet blockchain, I still wouldn't have a fully native Python API to ethereum (e.g. from Django) since pyetherum will need to run in some sort of daemon / process mode to continuously download blocks.
However, it is possible to add scripts ("services") to pyethereum that can be run against newly downloaded transactions. While this is very cool, it's not entirely what I'm looking for for my current project.
- pyethapp is rather slow when downloading the blockchain. The production blockchain might take days.
- pyethapp doesn't interface directly but can expose a RPC API. But in that case I'm better of using a geth node in stead.
- pyethapp seems to have some issues ;)
- pyethapp is (currently) python2.7 which makes it hard to interface with python3.x
It turns out my reported issue is partially known and has been for about three months now. It turns out at this moment pyethereum/pyethapp chokes on a specific transaction and code devs are having a hard time fixing it.