{"id":336,"date":"2016-02-26T18:00:27","date_gmt":"2016-02-26T17:00:27","guid":{"rendered":"http:\/\/benoit-alessandroni.fr\/?p=336"},"modified":"2016-03-03T12:05:15","modified_gmt":"2016-03-03T11:05:15","slug":"ethereum-partie-1","status":"publish","type":"post","link":"https:\/\/www.balessan.me\/technique\/blockchain\/ethereum-partie-1\/","title":{"rendered":"Ethereum &#8211; Cr\u00e9ation d&#8217;un r\u00e9seau priv\u00e9 de test"},"content":{"rendered":"<p>Dans ce premier article de la s\u00e9rie sur Ethereum suivant l&#8217;article d&#8217;introduction, je vais vous pr\u00e9senter les d\u00e9marches que j&#8217;ai effectu\u00e9s afin de d\u00e9ployer un r\u00e9seau priv\u00e9 sur ma machine.<\/p>\n<p><!--more--><\/p>\n<h2>1\u00e8re \u00c9tape: Installation<\/h2>\n<p><a href=\"https:\/\/www.ethereum.org\/cli\">Comme indiqu\u00e9 ici<\/a> la premi\u00e8re \u00e9tape est d&#8217;installer l&#8217;environnement et les utilitaires en ligne de commande. Nous avons alors le choix entre trois impl\u00e9mentations:<\/p>\n<ul class=\"listtype-bullet listindent1 list-bullet1\">\n<li>une en C++ apparemment \u00e0 privil\u00e9gier pour le d\u00e9veloppement ayant trait au IoT<\/li>\n<li>une en Go apparemment \u00e0 privil\u00e9gier pour le d\u00e9veloppement ayant trait au Frontend ?<\/li>\n<li>une en Python apparemment \u00e0 privil\u00e9gier pour le d\u00e9veloppement d&#8217;applications distribu\u00e9es bas\u00e9es sur les fondations d&#8217;Ethereum<\/li>\n<\/ul>\n<h3>Installation de Eth<\/h3>\n<p>Disclaimer: Finalement je ne me sers pas de Eth, mais de Geth, l&#8217;impl\u00e9mentation en Go du client ethereum. Si vous le souhaitez, vous pouvez donc passer cette section et aller directement \u00e0 la section &#8220;<a href=\"#geth_installation\">Installation de Geth<\/a>&#8221;<\/p>\n<p>J&#8217;opte tout naturellement pour la troisi\u00e8me solution, <a href=\"https:\/\/github.com\/ethereum\/pyethapp\">ce qui nous renvoie ici.<\/a> Le processus d'&#8221;install from source&#8221; demande de cloner les sources puis d&#8217;ex\u00e9cuter la commande:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">python setup.py install<\/pre>\n<p>Cette commande est un \u00e9chec, mais j&#8217;ai perdu la stack. Je tente donc l&#8217;installation via l&#8217;utilitaire Python Pip (voir README du projet Github)<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">pip install pyethapp<\/pre>\n<p>Apr\u00e8s divers t\u00e9l\u00e9chargements et ex\u00e9cutions d&#8217;installation de d\u00e9pendances, erreurs encore:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">command 'x86_64-linux-gnu-gcc' failed with exit status 1<\/pre>\n<p>D&#8217;apr\u00e8s Stack-overflow il me manquerait des librairies Python (plausibles, je ne suis pas un aficionados de Python). J&#8217;installe donc les libs python-dev et libevent-dev :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo apt-get install python-dev \r\nsudo apt-get install libevent-dev<\/pre>\n<p>Je relance :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">pip install pyethapp<\/pre>\n<p>Erreurs encore, mais sur l&#8217;absence de la librairie libffi. Voir le message dans la stack trace :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">No package 'libffi' found\r\nc\/_cffi_backend.c:13:17: fatal error: ffi.h: No such file or directory\r\n#include &lt;ffi.h&gt;<\/pre>\n<p>En parall\u00e8le, je me suis lanc\u00e9 dans l&#8217;installation de Geth, l&#8217;impl\u00e9mentation en Go, et tout s&#8217;est bien pass\u00e9 lors de l&#8217;ex\u00e9cution de la commande pr\u00e9cis\u00e9e dans la doc:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">bash &lt;(curl https:\/\/install-geth.ethereum.org -L)<\/pre>\n<p>Ce bash demande les droits d&#8217;admin, v\u00e9rifie notre distribution, et ensuite se comporte comme un grand.<br \/>\nRevenons donc \u00e0 nos moutons. Installation de la librairie libffi:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo apt-get install libffi6 libffi-dev\r\npip install pyethapp<\/pre>\n<p>La compilation (build) semble maintenant bien se passer mais un message d&#8217;erreur arrive finalement:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">Command \/usr\/bin\/python -c \"import setuptools, tokenize;__file__='\/tmp\/pip_build_balessan\/CodernityDB\/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))\" install --record \/tmp\/pip-Nk0bhH-record\/install-record.txt --single-version-externally-managed --compile failed with error code 1 in \/tmp\/pip_build_balessan\/CodernityDB\r\nStoring debug log for failure in \/home\/balessan\/.pip\/pip.log<\/pre>\n<p>Cela ressemble \u00e0 une impossibilit\u00e9 d&#8217;acc\u00e8der ou d&#8217;\u00e9crire dans certains r\u00e9pertoires \u00e0 la racine du disque. Apr\u00e8s tentative, une ex\u00e9cution via sudo (donc avec les droits root) a r\u00e9gl\u00e9 le probl\u00e8me donc:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo pip install pyethapp<\/pre>\n<p>Sortie de la console:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">Successfully installed CodernityDB pyyaml leveldb ethereum gevent gipc pbkdf2 devp2p statistics werkzeug scrypt ipython repoze.lru pysha3 bitcoin pycryptodome pyethash greenlet ipaddress pyelliptic tox tinyrpc coverage c-secp256k1 docutils pickleshare simplegeneric traitlets pluggy py cffi path.py ipython-genutils pycparser\r\nCleaning up...<\/pre>\n<p>Ca parait pas mal, plus qu&#8217;\u00e0 comprendre comment \u00e7a fonctionne !<\/p>\n<p>Nota Bene : Finalement je ne vais pas me servir de l&#8217;impl\u00e9mentation Python tout de suite, car mes tests suivants ne sont pas limit\u00e9s par le choix de Geth plut\u00f4t que Eth.<\/p>\n<h3><span id=\"geth_installation\">Installation de Geth<\/span><\/h3>\n<p>Pour installer Geth, rien de plus simple. La documentation officielle fournit la commande, qui est la suivante (sur Mac et Linux):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">bash &lt;(curl https:\/\/install-geth.ethereum.org -L)<\/pre>\n<p>Je n&#8217;ai pas conserv\u00e9 de copie de la sortie de la console, mais de m\u00e9moire tout s&#8217;\u00e9tait bien pass\u00e9 \u00e0 la premi\u00e8re tentative.<\/p>\n<h2>2\u00e8me \u00e9tape: Utilisation de Geth<\/h2>\n<p>Pour entrer dans la console interactive fournie \u00e0 l&#8217;installation de Geth, il suffit d&#8217;entrer:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">geth console<\/pre>\n<p>Suite \u00e0 cette commande, j&#8217;entre temporairement dans ce qui ressemble \u00e0 une invite de commandes, puis blockchain commence \u00e0 r\u00e9aliser des transactions ? WTF ?<\/p>\n<p>Information importante dans la documentation:<\/p>\n<blockquote><p>ATTENTION: If you just want to test the technology and play\u00a0 around, DON&#8217;T USE THE MAIN NETWORK. Read further to find out how to\u00a0 deploy a private test network without spending your ether.<\/p><\/blockquote>\n<p>Donc d\u00e9ploiement d&#8217;un r\u00e9seau de test avant d&#8217;aller plus loin !<\/p>\n<h2>3\u00e8me \u00e9tape: D\u00e9ploiement du r\u00e9seau<\/h2>\n<p>Avant de pouvoir ex\u00e9cuter la commande de d\u00e9ploiement du r\u00e9seau de test, il faut apparemment cr\u00e9er un fichier <b>genesis.<\/b><br \/>\nPour cela, suivre les instructions pr\u00e9sentes dans <a href=\"https:\/\/blog.ethereum.org\/2015\/07\/27\/final-steps\/\">ce post de blog<\/a>\u00a0(que je vais r\u00e9sumer ici).<\/p>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"1\">\n<li>R\u00e9cup\u00e9ration du script de g\u00e9n\u00e9ration du fichier<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">curl -O https:\/\/raw.githubusercontent.com\/ethereum\/genesis_block_generator\/master\/mk_genesis_block.py<\/pre>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"2\">\n<li>Installation de la lib python bitcoin (done lors des \u00e9tapes pr\u00e9c\u00e9dentes, mais au cas o\u00f9)<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo pip install bitcoin<\/pre>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"3\">\n<li>Mise \u00e0 jour de la lib<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo pip install --upgrade bitcoin<\/pre>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"4\">\n<li>G\u00e9n\u00e9ration du fichier, apr\u00e8s avoir fouill\u00e9 pour trouver le bon hash<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">python mk_genesis_block.py --extradata 0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa &gt; genesis_block.json<\/pre>\n<p>L\u00e0 le process r\u00e9fl\u00e9chit (enfin fais plein de trucs quoi).<\/p>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"5\">\n<li>Finalement une erreur apparait<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">Traceback (most recent call last):\r\nFile \"mk_genesis_block.py\", line 293, in &lt;module&gt;\r\nprint json.dumps(evaluate(), indent=4)\r\nFile \"mk_genesis_block.py\", line 285, in evaluate\r\np = list_purchases(th)\r\nFile \"mk_genesis_block.py\", line 224, in list_purchases\r\nt = get_block_timestamp([x['height'] - 1 for x in subpq])\r\nFile \"mk_genesis_block.py\", line 153, in new_method\r\nc[str(arg)] = method(arg)\r\nFile \"\/usr\/local\/lib\/python2.7\/dist-packages\/bitcoin\/bci.py\", line 472, in get_block_timestamp\r\n\"%Y-%m-%dT%H:%M:%SZ\")) for x in k['data']}\r\nTypeError: 'NoneType' object is not iterable<\/pre>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"6\">\n<li>Ex\u00e9cution de la commande en super-user<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo python mk_genesis_block.py --extradata 0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa &gt; genesis_block.json<\/pre>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"7\">\n<li>Maintenant c&#8217;est coh\u00e9rent:<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">Listed purchases\r\nComputed purchases\r\nFinished, total purchased: 60108506260000000000000000\r\nFoundation wallet creator address: 5abfec25f74cd88437631a7731906932776356f9\r\nFoundation balance: 11901484239480000000000000<\/pre>\n<p>On continue !<\/p>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"8\">\n<li>On lance le r\u00e9seau priv\u00e9:<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">geth --networkid 12345 --genesis ~\/blockchain\/genesis_block.json --datadir ~\/.ethereum_experiment console<\/pre>\n<p>Dans les arguments, l&#8217;argument\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">--genesis ~\/blockchain\/genesis_block.json<\/code> est le chemin vers le fichier genesis_block.json g\u00e9n\u00e9r\u00e9 pr\u00e9c\u00e9demment et l&#8217;argument \u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">--datadir ~\/.ethereum_experiment console<\/code>\u00a0 est le chemin vers le r\u00e9pertoire dans lequel vous souhaitez stocker les donn\u00e9es concernant votre r\u00e9seau, \u00e0 modifier selon votre envie (en notant tout de m\u00eame que le chemin par d\u00e9faut pour le stockage des informations est ~\/.ethereum\/, donc \u00e9vitez de l&#8217;occuper si vous souhaittez vous raccrocher \u00e0 la blockchain publique plus tard).<\/p>\n<ol class=\"listtype-number listindent1 list-number1\" start=\"9\">\n<li>Nous arrivons alors sur une invite de commandes:<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">instance: Geth\/v1.3.3\/linux\/go1.5.1\r\ndatadir: \/home\/balessan\/.ethereum_experiment\r\ncoinbase: null\r\nat block: 0 (Thu, 01 Jan 1970 01:00:00 CET)\r\nmodules: admin:1.0 db:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 shh:1.0 txpool:1.0 web3:1.0\r\n&gt;<\/pre>\n<p>Maintenant, pour tester quoi que ce soit on saute \u00e0 la section <a href=\"https:\/\/www.ethereum.org\/cli\">&#8220;Creating Accounts&#8221; dans la documentation<\/a>. Pour mon besoin, qui est d&#8217;investiguer les m\u00e9canismes de transaction et les applications possibles des smarts contracts, j&#8217;ai cr\u00e9\u00e9 deux comptes diff\u00e9rents, en utilisant bien \u00e9videmment la commande:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">personal.newAccount(\"Ta super passphrase de la mort qui tue !\")<\/pre>\n<p>Je peux ensuite v\u00e9rifier la cr\u00e9ation de mes comptes via la commande:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">&gt; eth.accounts<\/pre>\n<p>Qui me confirme la creation de deux comptes:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">&gt; [\"0xaf51314e6a721f234e132428745e0cb99a43faa2\", \"0x191e265ae0814b7e23e666221a8f628250a50027\"]<\/pre>\n<h2>Conclusion<\/h2>\n<p>Dans cet article, je vous ai pr\u00e9sent\u00e9 le process que j&#8217;ai suivi pour arriver \u00e0 avoir un r\u00e9seau priv\u00e9 de test qui fonctionne, en partant de la documentation officielle. Dans l&#8217;article qui suit je vous pr\u00e9senterais comment r\u00e9aliser des transactions de base et nous aborderons le sujet du minage, en pratique.<\/p>\n<p><a href=\"http:\/\/benoit-alessandroni.fr\/technique\/blockchain\/ethereum\/\">Retour \u00e0 l&#8217;accueil de la s\u00e9rie<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans ce premier article de la s\u00e9rie sur Ethereum suivant l&#8217;article d&#8217;introduction, je vais vous pr\u00e9senter les d\u00e9marches que j&#8217;ai effectu\u00e9s afin de d\u00e9ployer un r\u00e9seau priv\u00e9 sur ma machine.<\/p>\n","protected":false},"author":1,"featured_media":414,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coopedia_published":false},"categories":[53],"tags":[],"_links":{"self":[{"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/posts\/336"}],"collection":[{"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/comments?post=336"}],"version-history":[{"count":19,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/posts\/336\/revisions"}],"predecessor-version":[{"id":342,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/posts\/336\/revisions\/342"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/media\/414"}],"wp:attachment":[{"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/media?parent=336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/categories?post=336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/tags?post=336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}