{"id":2541,"date":"2017-08-15T18:53:39","date_gmt":"2017-08-15T16:53:39","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=2541"},"modified":"2023-06-08T15:36:42","modified_gmt":"2023-06-08T13:36:42","slug":"2541","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/08\/15\/2541\/","title":{"rendered":"Dapp Development on Ethereum"},"content":{"rendered":"<p>In this blog entry we take a look at how to develop a Dapp (\u2018decentralized app\u2019) on the Ethereum blockchain network and enhance our development process through Gitlab&#8217;s continuous integration (CI) services. It is part of the examination for the lecture &#8220;Software Development for Cloud Computing&#8221;.<\/p>\n<p>First, all the necessary technologies to develop a Dapp are shown and explained, followed by an example of a crowd funding smart contract. Finally, a possible CI setup for this kind of application is shown.<\/p>\n<p><!--more--><\/p>\n<h1>Blockchain<\/h1>\n<p>A blockchain is an open, distributed ledger that can record transactions between two parties efficiently and in a verifiable and permanent way. All these transactions are stored by each participant and are synchronized between them. The ledger itself consists of a chain of blocks (therefore the name Blockchain), and each block contains several transactions. New transactions are added to the most recent block, and after this block is &#8220;mined&#8221;, it is linked to the chain and a new block of transactions is started.<\/p>\n<p>The process of &#8220;mining&#8221; involves finding a proof-of-work for the latest block, in order to guarantee that considerable effort was made. Since every participant is working on the longest end of this generated chain, manipulations in earlier blocks are only possible if one has more computational power than the rest of the network. As an incentive to have as many competitors for block generation as possible, the one who finds the correct proof-of-work first receives a small amount of coins, called blockreward.<\/p>\n<h1>Ethereum<\/h1>\n<h1><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/eth_logo.png\" target=\"_blank\" rel=\"https:\/\/www.ethereum.org\/ noopener\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2550\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/08\/15\/2541\/eth_logo\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/eth_logo.png\" data-orig-size=\"271,186\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"eth_logo\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/eth_logo.png\" class=\"alignnone wp-image-2550 size-full\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/eth_logo.png\" alt=\"Ethereum\" width=\"271\" height=\"186\"><\/a><\/h1>\n<p>The Ethereum project was started around 2014 as a platform for smart contract development. It is built on blockchain technology, representing a distributed, secure-by-design database. This global infrastructure allows us to represent ownership and move property between network participants.<\/p>\n<p>Ethereum can be seen as a second generation blockchain platform, if we would count Bitcoin as the first. The biggest step forward was the introduction of smart contracts. Instead of having each transaction only carry a certain amount of &#8220;coins&#8221;, now you can also store code, which is supposed to interact with the data in the blockchain.<\/p>\n<p>Another improvement was a new proof-of-work concept. Bitcoin&#8217;s proof-of-work has the inherent problem that specialized hardware (so-called ASIC) is much better at mining than regular hardware. Thus, the amount of possible competitors for the generation of the next block decreased a lot over time, since often the power consumption costs were higher than the value gained through mining. In Ethereum, the proof-of-work was changed so that regular GPU&#8217;s are already indirectly optimized for this kind of task.<\/p>\n<h1>Smart Contracts<\/h1>\n<p>Smart contracts allow us to exchange property, or anything of value in that matter, in a secure and conflict-free way without the need for a middle man. They not only define rules and penalties of an agreement like in a regular contract, but also enforce those obligations automatically. Smart contracts could be compared to a vending machine: You fulfill some requirement (e.g. putting a coin in the vending machine), and you automatically earn the expected results.<\/p>\n<p>In Ethereum, smart contracts received their own scripting language called Solidity, which targets the Ethereum Virtual Machine (EVM). &nbsp;With it we can develop similar to other programming languages, besides some smaller quirks due to the unique nature of a Blockchain.<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"hidden\" data-highlight=\"\" data-caption=\"Example contract taken from the Ethereum website. It creates a simple custom token which can be transfered between multiple parties\">contract MyToken {\n    \/* This creates an array with all balances *\/\n    mapping (address =&gt; uint256) public balanceOf;\n\n    \/* Initializes contract with initial supply tokens to the creator of the contract *\/\n    function MyToken(uint256 initialSupply) {\n        balanceOf[msg.sender] = initialSupply;              \/\/ Give the creator all initial tokens\n    }\n\n    \/* Send coins *\/\n    function transfer(address _to, uint256 _value) {\n        if (balanceOf[msg.sender] &lt; _value) throw;           \/\/ Check if the sender has enough\n        if (balanceOf[_to] + _value &lt; balanceOf[_to]) throw; \/\/ Check for overflows\n        balanceOf[msg.sender] -= _value;                     \/\/ Subtract from the sender\n        balanceOf[_to] += _value;                            \/\/ Add the same to the recipient\n    }\n}<\/pre>\n<p>The idea now is that every contract also has an address, similar to regular participants in the network. This means that they can be the recipient of a transaction, allowing the usual transfer of funds, and also of instructions, i.e. calls to the contract&#8217;s member functions, through our supplied code in the transaction.<\/p>\n<p>Since the data is stored in a tamper-free way, it can, for instance, be used for verification purposes. One could implement a smart contract imitating the traditional land register, without the need for additional notary services. Or a company could use this technology for its supply chain management, to prove the point of origin for each of their products.<\/p>\n<p>The possibilities are seemingly endless and it is obvious that many current systems could be improved with this kind of technology. However, there are, of course, also drawbacks. For one, the concept of &#8220;proof-of-work&#8221; to guarantee the integrity of the network requires a lot of computational power and therefore comes with a high power consumption. There are some new techniques in development (-&gt; proof-of-stake) to remedy this issue, but currently it still has to be taken into account. Also, for some applications the openness of a Blockchain may be problematic. Nevertheless, we should keep in mind that blockchain technology in general is also just another tool among others in our software development toolbox, which may be good for certain applications, but has limitations regarding others.<\/p>\n<h1>Structure of a Dapp<\/h1>\n<p>A decentralized app (or Dapp) is an application that makes use of Ethereum smart contracts in the background. Therefore each Dapp requires access to the Ethereum network somehow. Ethereum offers several, open-source clients, the most popular ones being:<\/p>\n<ul>\n<li>Geth (Implementation in Go)<\/li>\n<li>Eth (Implementation in C++)<\/li>\n<li>Pyethapp (Implementation in Python)<\/li>\n<\/ul>\n<p>Through them we are able to read from or write to the blockchain. They all offer more or less the same functionality, however Ethereum didn&#8217;t want to limit themselves to one client only for security purposes. By default, those clients offer a console environment to pass commands. In the case of a Dapp, though, we need this interface in our (web) application. Therefore we can set the client to act as a so-called JSON-RPC endpoint to supply a JavaScript interface &#8211; called web3 &#8211; on an arbitrary port. In our application, we only need to load the web3 library, and connect it to the RPC endpoint. Now we are able to access all important features of the Ethereum client in our JavaScript application.<\/p>\n<h1>MetaMask<\/h1>\n<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/metamask_logo.jpg\" target=\"_blank\" rel=\"https:\/\/metamask.io\/ noopener\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2548\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/08\/15\/2541\/metamask_logo\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/metamask_logo.jpg\" data-orig-size=\"162,173\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"metamask_logo\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/metamask_logo.jpg\" class=\"alignnone wp-image-2548 size-full\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/metamask_logo.jpg\" alt=\"MetaMask\" width=\"162\" height=\"173\"><\/a><\/p>\n<p>MetaMask is a useful browser plugin to manage identities of a blockchain. If we consider that we are a visitor on a Dapp website, for instance related to crowd funding, then of course we need a way to verify our Ethereum account (i.e. a simple SSH-key) in order to be able to transfer funds from it to the Dapp. In the most simple way, we could just copy their contract address (and probably it&#8217;s interface defined in JSON) and make the transaction locally on our Ethereum client. However, this approach is rather unintuitive and uncomfortable to use, and we would obviously also need the fully downloaded blockchain (multiple gigabytes of data for official networks) first. There are also various public RPC endpoints available, that provide the web3 interface of a certain network, but the issue of account management still remains. We could now read data from the chain without having it downloaded locally, but writing still requires an identity in the network.<\/p>\n<p>MetaMask now solves this issue by injecting the accounts managed by the plugin itself into the source code of the web application, while offering easy RPC connections to external networks. Now writing to the external blockchain is possible, provided that we have enough funds in our account on that network to afford the transaction fees. One thing to note, though, is that the accounts managed by the Ethereum client directly cannot be accessed if MetaMask is used, since they will be replaced by MetaMask&#8217;s accounts.<\/p>\n<h1>Truffle<\/h1>\n<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/truffle_logo.png\" target=\"_blank\" rel=\"http:\/\/truffleframework.com\/ noopener\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2547\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/08\/15\/2541\/truffle_logo\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/truffle_logo.png\" data-orig-size=\"225,225\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"truffle_logo\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/truffle_logo.png\" class=\"alignnone wp-image-2547 size-full\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/truffle_logo.png\" alt=\"Truffle\" width=\"225\" height=\"225\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/truffle_logo.png 225w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/truffle_logo-150x150.png 150w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>We need some way to deploy our smart contracts on the Ethereum network. Initially they are written in Solidity, then they need to be compiled into byte-code, and finally this byte-code is added to a transaction and deployed on the network. On the other hand, we probably want to interact with this contract once it is deployed from our web application, so we need some JavaScript abstraction of it. We could do all this manually by using the web3 interface, it is however a rather exhausting and error-prone approach. Instead, we can use Truffle, a development framework for Ethereum, which allows us to easily develop, test, and deploy Ethereum smart contracts.<\/p>\n<p>After some quick initial configurations, the interaction between contract and application becomes a breeze compared to using web3, while many more included features make our developer life much easier. From the perspective of our web application, we now receive a JavaScript interface for each contract, and one function call will get translated to a transaction on the blockchain on the fly.<\/p>\n<p>Truffle also allows us test contracts either directly in Solidity, or in JavaScript. The first uses libraries of Truffle for contract assertions, which are, in essence, comprised of other smart contracts. The latter uses the Mocha testing framework for automated testing and Chai for assertions.<\/p>\n<p>Furthermore, Truffle also takes care of network management. During smart contract development, we usually want to have multiple networks available to deploy on. At least, we want to have one for contract testing, and one for final contract deployment. This is because if we would only use a live network, we could probably not fully test our contracts without spending a lot of real money (remember: Even the contract deployment itself costs transaction fees), and possible bugs could ruin our project before it really began. Ethereum therefore offers dedicated development networks, in which the mining process is simplified and Ether (The currency used in Ethereum) is very easy to obtain. Still, for some test scenarios having to mine Ether first, even though it is rather quick, can be a nuisance, so our alternative would be to create our own blockchain network and give our accounts some starting funds.<\/p>\n<p>Luckily for us, we can avoid having to go through this arduous process, as there is already a finished solution called Test-RPC, an Ethereum client dedicated to development and testing. It basically creates a whole blockchain with one console call and also has some more features specifically for testing.<\/p>\n<h1>Crowd Funding as a Smart Contract<\/h1>\n<p>Crowd funding is one of the model-applications of a smart contract. All the necessary constraints are in place, like having a fully transparent transaction process, a way to guarantee certain terms for both recipient and donator, and an equal treatment of all participants.<\/p>\n<p>But first, we need to define some rules. These can be arbitrary and depend on personal preference. For instance:<\/p>\n<ul>\n<li>Each crowd funded project has some funding goal and some deadline, and general information about the project itself and the backers so far<\/li>\n<li>The Beneficiary is only allowed to withdraw the money once the deadline has passed and the funding goal was reached<\/li>\n<li>The backers can withdraw their money again at any time before the deadline, afterwards only if the funding goal was not reached<\/li>\n<\/ul>\n<p>We could of course expand this, but it should suffice for a simple demonstration. So our next step is to translate those rules into a smart contract, for instance called &#8220;Campaign&#8221;. Error handling or logging is not included for simplicity.<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"hidden\" data-highlight=\"\" data-caption=\"Campaign contract\">pragma solidity ^0.4.0;\n\ncontract Campaign {\n    address public beneficiary;\n    string public title;\n    string public description;\n    uint public deadline;\n    uint public amountBacked;\n    uint public fundingGoal;\n    mapping(address =&gt; uint) public backers;\n    address[] public backerAddresses;\n\n    \/\/ Constructor of the contract\n    function Campaign(address _beneficiary, string _title, string _description, uint durationInMinutes, uint _fundingGoal) {\n        beneficiary = _beneficiary;\n        title = _title;\n        description = _description;\n        deadline = now + durationInMinutes * 1 minutes; \/\/ \"now\" is a keyword in Solidity and returns the current block timestamp\n        fundingGoal = _fundingGoal;\n    }\n\n\n    \/\/ Function is called if this contract is the recipient of a transaction\n    function () public payable {\n        if (now &lt; deadline) {\n            if (!isBacker(msg.sender)) {\n              backerAddresses.push(msg.sender);\n            }\n            backers[msg.sender] += msg.value;\n            amountBacked += msg.value;\n        }\n    }\n\n    \/\/ Function to withdraw money from the contract\n    function withdraw() {\n        \/\/ After deadline\n        if (now &gt;= deadline) {\n            \/\/ Goal was reached\n            if (amountBacked &gt;= fundingGoal) {\n                \/\/ Function caller is beneficiary\n                if (msg.sender == beneficiary) {\n                    msg.sender.send(amountBacked);\n                }\n            } else {\n                \/\/ Not enough money raised\n                uint amount = backers[msg.sender];\n                if (amount &gt; 0) {\n                    if (msg.sender.send(amount)) {\n                        backers[msg.sender] = 0;\n                    }\n                }\n            }\n        }\n        \/\/ Before deadline\n        else {\n            amount = backers[msg.sender];\n            if (amount &gt; 0) {\n                if (msg.sender.send(amount)) {\n                    backers[msg.sender] = 0;\n                    amountBacked -= amount;\n                }\n            }\n        }\n    }\n\n    \/\/ Function to check if backerAddress is a backer\n    function isBacker(address backerAddress) public constant returns (bool) {\n      for (uint i = 0; i &lt; backerAddresses.length; ++i) {\n        if (backerAddresses[i] == backerAddress) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n}&lt;br&gt;<\/pre>\n<p>In our case, it is also useful to have a second contract &#8220;CampaignManager&#8221;, through which new campaigns are created.<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"hidden\" data-highlight=\"\" data-caption=\"CampaignManager Contract\">pragma solidity ^0.4.0;\n\n\/\/ Our Campaign contract\nimport \".\/Campaign.sol\";\n\ncontract CampaignManager {\n    function CampaignManager() {}\n\n    \/\/ Function to create a new campaign\n    function newCampaign(address beneficiary, string title, string description, uint durationInMinutes, uint fundingGoalInEther) {\n        new Campaign(beneficiary, title, description, durationInMinutes, fundingGoalInEther);\n    }\n}<\/pre>\n<p>Once we have our contracts implemented, we can use Truffle to do the rest. First, we need to call &#8220;truffle compile&#8221; in our project directory (make sure &#8220;truffle init&#8221; was used to create the project in the beginning) to generate the contract artifacts. Next, we need to call &#8220;truffle migrate &lt;network&gt;&#8221; (after correct migration configuration, best work on the truffle example project first and go through the truffle tutorials to better understand the inner workings) to deploy the contract (in our case the CampaignManager) on the blockchain. We do not want to create the Campaign contract just now, as this should be done through our web application. Make sure beforehand that an RPC endpoint is running and truffle has the correct address of it in the &#8220;truffle.js&#8221; config file. Now the contract is ready for use on the blockchain.<\/p>\n<p>To interact with it on our javascript application side, the following needs to be done:<\/p>\n<ul>\n<li>Import web3 and truffle-contract library<\/li>\n<li>Import generated contract artifacts<\/li>\n<li>Create javascript contract interface, e.g. &#8220;var Campaign = truffle-contract(campaign_artifacts)&#8221;<\/li>\n<li>On load, set the web3 provider like &#8220;window.web3 = new Web3(web3.currentProvider);&#8221;, make sure MetaMask is running<\/li>\n<\/ul>\n<p>Afterwards, we are free to interact with the contract as we please. An example of creating a new campaign in javascript:<\/p>\n<pre class=\"prettyprint lang-javascript\" data-start-line=\"1\" data-visibility=\"hidden\" data-highlight=\"\" data-caption=\"Contract Creation in JavaScript\">\/\/ Get the variables from a form for example\nvar beneficiary = form.beneficiary.value;\nvar title = form.title.value;\nvar description = form.description.value;\nvar duration = form.duration.value;\nvar fundingGoal = form.fundingGoal.value;\n\nCampaignManager.deployed().then(function(instance) {\n      \/\/ Get the accounts before each contract interaction. This is necessary since the user might change the available accounts while the web application is running\n      web3.eth.getAccounts(function (err, accounts) {\n        if (accounts[0]) {\n          \/\/ Gas price is depending on the size of the transaction, here it is probably too much\n          instance.newCampaign(beneficiary, title, description, duration, fundingGoal, {from: accounts[0], gas: 2000000});\n        }\n      });\n    });<\/pre>\n<p>Once everything is set up, it really is quite easy.<\/p>\n<h1>Gitlab Continuous Integration<\/h1>\n<p><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/gitlab_logo.png\" target=\"_blank\" rel=\"https:\/\/about.gitlab.com\/ noopener\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2546\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/08\/15\/2541\/gitlab_logo\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/gitlab_logo.png\" data-orig-size=\"234,216\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"gitlab_logo\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/gitlab_logo.png\" class=\"alignnone wp-image-2546\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/08\/gitlab_logo.png\" alt=\"Gitlab\" width=\"260\" height=\"240\"><\/a><\/p>\n<p>To make the whole development process more smooth, a CI setup is recommended. In our crowd funding case, a&nbsp;three-step setup consisting of a build, test, and deploy stage is all we need to perform all necessary operations. As we have seen from before, we basically need to take care of two separate clients: One is the JSON-RPC endpoint, i.e. an Ethereum client, and the other is our web application. To keep things simple and clean, we use Docker for all clients. Assuming that we want to deploy our web application on a dedicated hosted server somewhere, we first need to setup the ssh connection in a &#8220;before_script&#8221; in our Gitlab CI yaml file.&nbsp;Then we start with the build stage, and perform the following:<\/p>\n<ul>\n<li>Pull the Ethereum client docker image and the web app repo data on the remote server<\/li>\n<li>Build docker image for our web app on the remote server, containing a truffle migrate command<\/li>\n<li>Pull Test-RPC docker image and setup truffle in the Gitlab runner environment<\/li>\n<li>Start Test-RPC docker container on the runner<\/li>\n<li>Run truffle compile and migrate on the runner<\/li>\n<\/ul>\n<p>Now we have two docker images on our remote server, and the running Test-RPC container in the runner environment. Next, we can continue with the test stage:<\/p>\n<ul>\n<li>Run truffle test<\/li>\n<\/ul>\n<p>If the truffle tests were successful, we continue with deploy:<\/p>\n<ul>\n<li>Start RPC-Endpoint docker container on remote server<\/li>\n<li>Start Web app docker container on remote server<\/li>\n<\/ul>\n<p>On the remote server, we have to take into account that these two docker containers need to communicate with each other, and therefore need to be in the same docker network. Also, since we probably don&#8217;t want to download the entire blockchain after each restart, a docker volume is required to store the blockchain data independently of the docker containers on the remote server.<\/p>\n<p>&nbsp;<\/p>\n<h1>Conclusion<\/h1>\n<p>This project was rather full of new technologies for myself, as the whole Blockchain world was rather unknown to me before. Since it is still a rather recent technology, changes happen frequently and getting into it might prove difficult sometimes. Especially if one doesn&#8217;t know all the available methods and libraries to easen the Dapp development, it gets frustrating quickly. I hope that with this kind of collection of useful tools and a working example scenario others may find it easier to get into it. There is still a lot which is not covered in this blog entry, but atleast it helps to get onto the right track and not get lost in low-level details of developing on a blockchain. Once the general project setup with truffle, MetaMask, CI, and so on is done, further efforts can be entirely dedicated to the application itself without getting trouble from lower layers.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog entry we take a look at how to develop a Dapp (\u2018decentralized app\u2019) on the Ethereum blockchain network and enhance our development process through Gitlab&#8217;s continuous integration (CI) services. It is part of the examination for the lecture &#8220;Software Development for Cloud Computing&#8221;.<\/p>\n<p>First, all the necessary technologies to develop a Dapp are shown and explained, followed by an example of a crowd funding smart contract. Finally, a possible CI setup for this kind of application is shown.<\/p>\n","protected":false},"author":477,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[120,650,22],"tags":[],"ppma_author":[725],"class_list":["post-2541","post","type-post","status-publish","format-standard","hentry","category-cloud-technologies","category-scalable-systems","category-student-projects"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":4241,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/09\/06\/blockchain-risks-and-chances-2018-overview\/","url_meta":{"origin":2541,"position":0},"title":"Blockchain Risks and Chances \u2013 An 2018 Overview on Public and Private Blockchain, Smart Contracts, DAOs and ICOs","author":"Pirmin Rehm","date":"6. September 2018","format":false,"excerpt":"A few years ago, talking about Blockchain was largely consistent with talking about the technology behind Bitcoin. In contrast, Blockchain nowadays comprises a whole technology branch, whereby the Blockchain itself can be implemented in lots of various ways. Not a year ago, on December 17, 2018, the peak of the\u2026","rel":"","context":"In &quot;Secure Systems&quot;","block_context":{"text":"Secure Systems","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/system-designs\/secure-systems\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/09\/bc-layers.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/09\/bc-layers.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/09\/bc-layers.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/09\/bc-layers.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/09\/bc-layers.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/09\/bc-layers.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":7097,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/10\/23\/supply-chain-on-ethereum-network\/","url_meta":{"origin":2541,"position":1},"title":"Supply chain on Ethereum Network","author":"nr037","date":"23. October 2019","format":false,"excerpt":"600 million people - almost every tenth in the world - fall ill every year with contaminated food, 420,000 of them die (cf. World Health Organization 2019). The main reason for this are supply chains that can not be properly traced back to the source of the contamination (cf. Yiannas\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/ethereum-blockcahin.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/ethereum-blockcahin.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/ethereum-blockcahin.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/ethereum-blockcahin.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/ethereum-blockcahin.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/ethereum-blockcahin.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":3534,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/31\/supply-chain-management-using-blockchain-technology-hands-on-hyperledger-part-1\/","url_meta":{"origin":2541,"position":2},"title":"Supply Chain Management using Blockchain Technology &#8211; Hands-On Hyperledger (Part 1)","author":"df036@hdm-stuttgart.de","date":"31. March 2018","format":false,"excerpt":"Motivation Many of today's supply chain management (SCM) solutions still involve enormous amounts of manual work. The procedures required for proper record keeping often rely on manual input, which makes them slow and prone to errors. Additional terms, such as price agreements, conditions that must be strictly adhered to, as\u2026","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Fabric01_PeerNetwork-300x232.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":3530,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/31\/supply-chain-management-using-blockchain-technology-hands-on-hyperledger-part-2\/","url_meta":{"origin":2541,"position":3},"title":"Supply Chain Management using Blockchain Technology &#8211; Hands-On Hyperledger (Part 2)","author":"df036@hdm-stuttgart.de","date":"31. March 2018","format":false,"excerpt":"Implementation Model The model we've chosen is an attempt to implement one part of a large SCM business model. Since an example of shipping processes for single items does already exist on IBM's platform 'DeveloperWorks', we focused on the ability to create and place composite orders. During the definition of\u2026","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Participants-Screenshot-300x189.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2400,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/07\/15\/blockchain-revolution-or-hype\/","url_meta":{"origin":2541,"position":4},"title":"Blockchain &#8211; Revolution or hype?","author":"Korbinian Kuhn, Steffen Mauser","date":"15. July 2017","format":false,"excerpt":"Welcome to our journey through the blockchain, since the emergence of Bitcoin, one of the most trending topics of the global digital village. After reading this blog post, you\u2019ll have a basic understanding of the technology, a wide overview of future use cases and are able to differentiate between realistic\u2026","rel":"","context":"In &quot;Secure Systems&quot;","block_context":{"text":"Secure Systems","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/system-designs\/secure-systems\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/07\/10_applications.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/07\/10_applications.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/07\/10_applications.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/07\/10_applications.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":11460,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2020\/09\/29\/get-car-location-using-raspberrypi-and-google-cloud-iot-core\/","url_meta":{"origin":2541,"position":5},"title":"Get car location using Raspberry Pi and Google Cloud IoT Core","author":"Simon L\u00f6bert","date":"29. September 2020","format":false,"excerpt":"Project idea Have you ever been in the situation, that you parked your car somewhere in the city and some hours later, you couldn't remember where you parked it? You may wish to have an application on your smartphone, which is able to locate your car. From this consideration, the\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2020\/09\/grafik.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"jetpack_sharing_enabled":false,"authors":[{"term_id":725,"user_id":477,"is_guest":0,"slug":"ph047","display_name":"Patrick Hidringer","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/4925a02c9a4acf310a83363c235b0e28d15e44079306c667b47841630a7de0bd?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/2541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/477"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=2541"}],"version-history":[{"count":6,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/2541\/revisions"}],"predecessor-version":[{"id":24721,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/2541\/revisions\/24721"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=2541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=2541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=2541"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=2541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}