{"id":403,"date":"2016-03-25T18:00:39","date_gmt":"2016-03-25T17:00:39","guid":{"rendered":"http:\/\/benoit-alessandroni.fr\/?p=403"},"modified":"2016-03-12T18:01:56","modified_gmt":"2016-03-12T17:01:56","slug":"ethereum-partie-3","status":"publish","type":"post","link":"https:\/\/www.balessan.me\/technique\/blockchain\/ethereum-partie-3\/","title":{"rendered":"Ethereum &#8211; Impl\u00e9mentation d&#8217;un smart contract basique"},"content":{"rendered":"<p>Maintenant, continuons l&#8217;ex\u00e9cution du <a href=\"https:\/\/ethereum.org\/greeter\">tutoriel officiel \u00e0 la page suivante<\/a> dont le sujet va \u00eatre la premi\u00e8re cr\u00e9ation et utilisation d&#8217;un smart contract.<\/p>\n<h2>1\u00e8re \u00e9tape: relancer notre r\u00e9seau !<\/h2>\n<p>Comme toujours, il faut red\u00e9marrer le serveur en ex\u00e9cutant la commande:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">geth --networkid 12345 --genesis ~\/blockchain\/genesis_block.json --datadir ~\/.ethereum_experiment <b>--dev\u00a0--lightkdf\u00a0<\/b>--nodiscover\u00a0--maxpeers\u00a00 console<\/pre>\n<p>Comme vous pouvez le voir, j&#8217;ai ici utilis\u00e9 quelques arguments suppl\u00e9mentaires. En effet, pour une raison que j&#8217;ignore, le param\u00e9trage de la <em>difficulty<\/em> de r\u00e9solution des puzzles n&#8217;est plus pris en compte lorsque je relance le r\u00e9seau sur ma machine. Un contournement simple (mais peu document\u00e9) est d&#8217;utiliser les arguments &#8211;dev et &#8211;lightkdf qui simplifient\u00a0 grandement le minage !<\/p>\n<h2>2\u00e8me \u00e9tape: cr\u00e9ation de notre smart-contract !<\/h2>\n<p><a href=\"https:\/\/github.com\/ethereum\/go-ethereum\/wiki\/Contracts-and-Transactions\">Ici: le document officiel de r\u00e9f\u00e9rence sur le principe des smart contracts<\/a><\/p>\n<p>Premi\u00e8re \u00e9tape, installer le compilateur pour Solidity (langage haut-niveau qui permet l&#8217;impl\u00e9mentation et le test de smart contracts):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo add-apt-repository ppa:ethereum\/ethereum\r\nsudo apt-get update\r\nsudo apt-get install solc\r\nwhich solc\r\n<\/pre>\n<p>L&#8217;output de cette commande devrait correspondre \u00e0 \u00e7a:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">\/usr\/bin\/solc<\/pre>\n<p>Maintenant si vous retournez checker la liste de vos compilateurs via Geth (relancez le r\u00e9seau d&#8217;abord, voir \u00e9tape 1):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">eth.getCompilers()<\/pre>\n<p>Vous devriez avoir comme retour:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">[\"Solidity\"]<\/pre>\n<p>Ensuite, on suit la doc, afin d&#8217;essayer d&#8217;ex\u00e9cuter notre Greeter Smart Contract. Pour cela,<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'\r\nvar greeterCompiled = web3.eth.compile.solidity(greeterSource)<\/pre>\n<p>Puis:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">var _greeting = \"Hello World!\";\r\nvar greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);\r\nvar greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[0], data: greeterCompiled.greeter.code, gas: 300000}, function(e, contract){\r\nif(!e) {\r\nif(!contract.address) {\r\nconsole.log(\"Contract transaction send: TransactionHash: \" + contract.transactionHash + \" waiting to be mined...\");\r\n} else {\r\nconsole.log(\"Contract mined! Address: \" + contract.address);\r\nconsole.log(contract);\r\n}\r\n}\r\n})<\/pre>\n<p>Et maintenant, pour valider l&#8217;ex\u00e9cution du contrat, un petit<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">miner.start();<\/pre>\n<p>Ce qui nous fournit une confirmation:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">&gt; I0214 14:16:50.174101    5584 miner.go:119] Starting mining operation (CPU=4 TOT=5)\r\nI0214 14:16:50.174868    5584 worker.go:570] commit new work on block 12 with 1 txs &amp; 0 uncles. Took 739.867\u00b5s\r\nI0214 14:16:50.990070    5584 worker.go:349]\r\nMined block (#12 \/ 58455ccc). Wait 5 blocks for confirmation\r\nI0214 14:16:50.990425    5584 worker.go:570] commit new work on block 13 with 0 txs &amp; 0 uncles. Took 307.265\u00b5s\r\nI0214 14:16:50.990456    5584 worker.go:448] ??\r\nMined 5 blocks back: block #7\r\nI0214 14:16:51.070633    5584 worker.go:570] commit new work on block 13 with 0 txs &amp; 0 uncles. Took 294.004\u00b5s\r\nContract mined! Address: 0xbd4cb799aee37567835639dbba7f3eeb2c9141f1\r\n[object Object]<\/pre>\n<p>Le contrat a bien \u00e9t\u00e9 min\u00e9, son adresse est la suivante: 0xbd4cb799aee37567835639dbba7, il doit donc \u00eatre maintenant disponible sur ma blockchain priv\u00e9. Confirmons \u00e7a, en demandant au greeter son adresse:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">&gt; eth.getCode(greeter.address)\r\n\"0x606060405260e060020a600035046341c0e1b58114610026578063cfae321714610068575b005b6100246000543373ffffffffffffffffffffffffffffffffffffffff908116911614156101375760005473ffffffffffffffffffffffffffffffffffffffff16ff5b6100c9600060609081526001805460a06020601f6002600019610100868816150201909416939093049283018190040281016040526080828152929190828280156101645780601f1061013957610100808354040283529160200191610164565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b565b820191906000526020600020905b81548152906001019060200180831161014757829003601f168201915b505050505090509056\"<\/pre>\n<p>Et si on teste le contrat :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">greeter.greet();<\/pre>\n<p>Retour :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">\"Hello World!\"<\/pre>\n<p>\u00c9videmment, vous pouvez modifier \u00e0 souhait la valeur du greeting que vous passez \u00e0 votre objet greeter et ensuite le re-tester pour valider que la modification est bien prise en compte. Cela prouve que ce <strong>smart contract<\/strong> est bien <em>smart<\/em>, car il s&#8217;adapte aux informations qu&#8217;on lui fournit en entr\u00e9e. Si vous souhaitez relancer une ex\u00e9cution de votre contrat apr\u00e8s modification du greeting en entr\u00e9e, notez qu&#8217;il faut reminer \u00e0 chaque fois sa validation.<\/p>\n<h2>Conclusion<\/h2>\n<p>Nous avons vu dans cet article comment impl\u00e9menter et ex\u00e9cuter notre premier smart contract, qui n&#8217;a pas grand-chose de smart pour le moment. Les exemples et les explications de code s&#8217;\u00e9tofferont dans les articles \u00e0 venir, si jamais vous \u00eates rest\u00e9s sur votre faim ! En attendant, n&#8217;h\u00e9sitez pas \u00e0 me faire des remarques\/commentaires si certains passages ne sont pas clairs \ud83d\ude09<\/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>Maintenant, continuons l&#8217;ex\u00e9cution du tutoriel officiel \u00e0 la page suivante dont le sujet va \u00eatre la premi\u00e8re cr\u00e9ation et utilisation d&#8217;un smart contract. 1\u00e8re \u00e9tape: relancer notre r\u00e9seau ! Comme toujours, il faut red\u00e9marrer le serveur en ex\u00e9cutant la commande: geth &#8211;networkid 12345 &#8211;genesis ~\/blockchain\/genesis_block.json &#8211;datadir ~\/.ethereum_experiment &#8211;dev\u00a0&#8211;lightkdf\u00a0&#8211;nodiscover\u00a0&#8211;maxpeers\u00a00 console Comme vous pouvez le voir, j&#8217;ai [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":433,"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\/403"}],"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=403"}],"version-history":[{"count":7,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/posts\/403\/revisions"}],"predecessor-version":[{"id":426,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/posts\/403\/revisions\/426"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/media\/433"}],"wp:attachment":[{"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/media?parent=403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/categories?post=403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.balessan.me\/api\/wp\/v2\/tags?post=403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}