<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>JSLee&#39;s Blog</title>
    <link>https://j-s-lee.github.io/</link>
    <atom:link href="/rss2.xml" rel="self" type="application/rss+xml"/>
    
    <description></description>
    <pubDate>Mon, 27 Aug 2018 12:28:21 GMT</pubDate>
    <generator>http://hexo.io/</generator>
    
    <item>
      <title>Hyperledger Composer - Product Auction Network With Events</title>
      <link>https://j-s-lee.github.io/2018/08/27/product-auction-network-with-events/</link>
      <guid>https://j-s-lee.github.io/2018/08/27/product-auction-network-with-events/</guid>
      <pubDate>Mon, 27 Aug 2018 09:04:23 GMT</pubDate>
      <description>
      
        &lt;p&gt;이 글은 &lt;a href=&quot;https://github.com/IBM/BlockchainEvents-CompositeJourney&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Hyperledger Composer Composite Journey - Part.3&lt;/a&gt; 데모 실습을 정리한 글이다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://j-s-lee.github.io/2018/08/22/product-auction-network/&quot;&gt;상품 경매 네트워크 데모&lt;/a&gt; 에서 하이퍼레저 패브릭 네트워크에 비즈니스 네트워크를 배포하고, 배포된 비즈니스 네트워크에 REST API 서버를 연결하는 방법을 배웠다면,&lt;/p&gt;
&lt;p&gt;이번 과정에서는 하이퍼레저 패브릭 네트워크에서 이벤트가 발생하면, 외부 어플리케이션에서 웹소켓 이벤트 리스너를 통해 Web UI를 업데이트하는 방법을 알아보자.    &lt;/p&gt;
      
      </description>
      
      <content:encoded><![CDATA[<p>이 글은 <a href="https://github.com/IBM/BlockchainEvents-CompositeJourney" target="_blank" rel="noopener">Hyperledger Composer Composite Journey - Part.3</a> 데모 실습을 정리한 글이다.</p><p><a href="https://j-s-lee.github.io/2018/08/22/product-auction-network/">상품 경매 네트워크 데모</a> 에서 하이퍼레저 패브릭 네트워크에 비즈니스 네트워크를 배포하고, 배포된 비즈니스 네트워크에 REST API 서버를 연결하는 방법을 배웠다면,</p><p>이번 과정에서는 하이퍼레저 패브릭 네트워크에서 이벤트가 발생하면, 외부 어플리케이션에서 웹소켓 이벤트 리스너를 통해 Web UI를 업데이트하는 방법을 알아보자.    </p><a id="more"></a><!--toc--><h2 id="아카이브-생성"><a href="#아카이브-생성" class="headerlink" title="아카이브 생성"></a>아카이브 생성</h2><p>저장소 복제:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/IBM/BlockchainEvents-CompositeJourney.git</span><br></pre></td></tr></table></figure><p>아카이브 파일(<code>.bna</code>) 생성:</p><figure class="highlight javascript"><figcaption><span>~/demo/BlockchainEvents-CompositeJourney/Composer</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install</span><br></pre></td></tr></table></figure><p><code>{projectDir}/dist</code>에 <code>events.bna</code>파일이 생성되었다.</p><p>프로젝트 디렉토리에서 <code>npm test</code> 명령을 실행하면  <code>test/productAuction.js</code>에 작성된 테스트 코드로 유닛테스트가 가능하다.</p><h2 id="로컬-패브릭에서-실행되는-하이퍼레저-컴포저에-아카이브-배포"><a href="#로컬-패브릭에서-실행되는-하이퍼레저-컴포저에-아카이브-배포" class="headerlink" title="로컬 패브릭에서 실행되는 하이퍼레저 컴포저에 아카이브 배포"></a>로컬 패브릭에서 실행되는 하이퍼레저 컴포저에 아카이브 배포</h2><p>로컬 패브릭을 시작한 뒤 <code>events.bna</code> 파일이 들어있는 <code>dist</code> 디렉토리에서 다음 명령어를 통해 비즈니스 네트워크를 설치/시작한다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">composer network install --card PeerAdmin@hlfv1 --archiveFile events.bna</span><br><span class="line">composer network start --networkName events --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card</span><br><span class="line">composer card import --file networkadmin.card</span><br></pre></td></tr></table></figure><p>다음 명령을 통해 네트워크가 잘 배포되었는지 확인할 수 있다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer network ping --card admin@events</span><br></pre></td></tr></table></figure><p>이제 프로젝트 디렉토리로 이동해서 REST API 서버를 시작한다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">➜  BlockchainEvents-CompositeJourney git:(master) ✗ composer-rest-server</span><br><span class="line">? Enter the name of the business network card to use: admin@events</span><br><span class="line">? Specify <span class="keyword">if</span> you want namespaces <span class="keyword">in</span> the generated REST API: never use namespaces</span><br><span class="line">? Specify <span class="keyword">if</span> you want to use an API key to secure the REST API: No</span><br><span class="line">? Specify <span class="keyword">if</span> you want to <span class="built_in">enable</span> authentication <span class="keyword">for</span> the REST API using Passport:No</span><br><span class="line">? Specify <span class="keyword">if</span> you want to <span class="built_in">enable</span> event publication over WebSockets: Yes</span><br><span class="line">? Specify <span class="keyword">if</span> you want to <span class="built_in">enable</span> TLS security <span class="keyword">for</span> the REST API: No</span><br></pre></td></tr></table></figure><p>각 질문에 대해 답하면 이에 맞는 REST API 서버가 시작된다.    </p><ul><li>비즈니스 네트워크 카드 이름: <code>admin@events</code></li><li>생성된 API에서 네임스페이스 사용 여부: <code>Never use namespaces</code></li><li>API key 사용 여부: <code>No</code></li><li>Passport를 통한 인증 허용 여부: <code>No</code></li><li>웹소켓을 통한 이벤트 퍼블리싱 허용 여부: <code>Yes</code></li><li>TLS 보안 허용 여부: <code>No</code></li></ul><p>REST API 서버가 정상적으로 시작된 경우 웹브라우저로 <a href="http://localhost:3000/explorer" target="_blank" rel="noopener">http://localhost:3000/explorer</a> 로 이동하면 API를 볼 수 있다.    </p><h2 id="웹-UI-시작"><a href="#웹-UI-시작" class="headerlink" title="웹 UI 시작"></a>웹 UI 시작</h2><p>새 터미널을 열어서 프로젝트 디렉토리 내 <code>Web</code> 디렉토리로 이동한다.</p><p><code>npm install</code> 를 통해 모듈 설치 후 <code>node server.js</code> 명령을 사용해 노드 서버를 시작한다.</p><p><a href="http://localhost:8000/seller.html" target="_blank" rel="noopener">http://localhost:8000/seller.html</a>, <a href="http://localhost:8000/buyer.html" target="_blank" rel="noopener">http://localhost:8000/buyer.html</a> 에서 각각 판매자와 구매자의 이벤트에 대한 대시보드를 볼 수 있다.</p><h2 id="트랜잭션-submit"><a href="#트랜잭션-submit" class="headerlink" title="트랜잭션 submit"></a>트랜잭션 submit</h2><p><a href="">경매 네트워크 데모 실습</a>에서는 <code>composer playground</code>를 이용해 트랜잭션을 발생시켜 보았으니, 이번 실습에서는 REST API를 이용해 보겠다.</p><h4 id="참여자-생성"><a href="#참여자-생성" class="headerlink" title="참여자 생성"></a>참여자 생성</h4><p>참여자는 <code>Seller</code> 1명, <code>Member</code> 2명을 생성한다.</p><p>먼저 <code>POST /Seller</code>를 통해 <code>Seller</code>를 생성한다:</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Seller"</span>,</span><br><span class="line">  <span class="attr">"organisation"</span>: <span class="string">"ACME"</span>,</span><br><span class="line">  <span class="attr">"email"</span>: <span class="string">"auction@acme.org"</span>,</span><br><span class="line">  <span class="attr">"balance"</span>: <span class="number">100</span>,</span><br><span class="line">  <span class="attr">"products"</span>: []</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>파라미터 부분에 Seller 생성을 위한 JSON Data를 입력하고 <code>Try it out!</code> 버튼을 클릭하면 아래에 API 실행 결과가 나온다.</p><p><img src="/images/blockchainEvents/createSeller.png" alt="createSeller">    </p><p><code>Member</code> 생성도 동일한 방법으로 <code>POST /Member</code>를 통해 생성한다.</p><p>생성한 참여자들에게는 <code>POST /system/identities/issue</code> 를 통해 ID를 발급한다.</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"participant"</span>: <span class="string">"resource:org.acme.product.auction.Seller#auction@acme.org"</span>,</span><br><span class="line">  <span class="attr">"userID"</span>: <span class="string">"seller"</span>,</span><br><span class="line">  <span class="attr">"options"</span>: &#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="/images/blockchainEvents/issueID.png" alt="issueID">    </p><p><code>memberA</code>, <code>memberB</code>도 동일한 API를 통해 ID를 발급해준다.</p><h4 id="상품-추가"><a href="#상품-추가" class="headerlink" title="상품 추가"></a>상품 추가</h4><p><code>POST /AddProduct</code>를 통해 상품을 등록한다.</p><figure class="highlight json"><figcaption><span>POST /AddProduct</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.AddProduct"</span>,</span><br><span class="line">  <span class="attr">"productId"</span>: <span class="string">"iphone"</span>,</span><br><span class="line">  <span class="attr">"description"</span>: <span class="string">"sample product"</span>,</span><br><span class="line">  <span class="attr">"owner"</span>: <span class="string">"resource:org.acme.product.auction.Seller#auction@acme.org"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p> <code>POST /StartBidding</code>을 통해 경매를 시작한다.</p><figure class="highlight json"><figcaption><span>POST /StartBidding</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.StartBidding"</span>,</span><br><span class="line">  <span class="attr">"listingId"</span>: <span class="string">"sampleListingId"</span>,</span><br><span class="line">  <span class="attr">"reservePrice"</span>: <span class="number">50</span>,</span><br><span class="line">  <span class="attr">"product"</span>: <span class="string">"resource:org.acme.product.auction.Product#iphone"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="경매-입찰"><a href="#경매-입찰" class="headerlink" title="경매 입찰"></a>경매 입찰</h4><p><code>Member</code>는 <code>POST /Offer</code>를 통해 경매에 참여할 수 있다.</p><figure class="highlight json"><figcaption><span>memberA POST /Offer</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Offer"</span>,</span><br><span class="line">  <span class="attr">"bidPrice"</span>: <span class="number">180</span>,</span><br><span class="line">  <span class="attr">"listing"</span>: <span class="string">"resource:org.acme.product.auction.ProductListing#sampleListingId"</span>,</span><br><span class="line">  <span class="attr">"member"</span>: <span class="string">"resource:org.acme.product.auction.Member#memberA@acme.org"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight json"><figcaption><span>memberB POST /Offer</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Offer"</span>,</span><br><span class="line">  <span class="attr">"bidPrice"</span>: <span class="number">300</span>,</span><br><span class="line">  <span class="attr">"listing"</span>: <span class="string">"resource:org.acme.product.auction.ProductListing#sampleListingId"</span>,</span><br><span class="line">  <span class="attr">"member"</span>: <span class="string">"resource:org.acme.product.auction.Member#memberB@acme.org"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>    <h4 id="Web-UI를-통한-경매-현황-확인"><a href="#Web-UI를-통한-경매-현황-확인" class="headerlink" title="Web UI를 통한 경매 현황 확인"></a>Web UI를 통한 경매 현황 확인</h4><blockquote><p>웹소켓을 통한 이벤트 퍼블리싱 허용 여부: <code>Yes</code></p></blockquote><p>우리가 REST API 서버를 시작할 때 선택한 옵션 중 다음 옵션에 의해서 API 호출 시 발생하는 이벤트를 노드 서버에서 받을 수 있다.</p><p>대시보드를 보여주는 웹 어플리케이션의 루트 디렉토리인 <code>Web</code> 디렉토리의 내부를 보면 <code>Web/scripts/events.js</code> 가 있다.</p><p>이 스크립트는  <code>ws://localhost:3000</code>에 대한 이벤트 리스너가 정의되어 있고 이를 통해 이벤트가 발생할 때 Web UI를 업데이트 시켜준다.</p><p>아래는 지금까지의 경매 현황을 보여주는 <code>Seller</code>와 <code>Member</code>의 대시보드이다.</p><p>최소 금액 50으로 경매가 시작되고, <code>memberA</code>와 <code>memberB</code>가 입찰한 정보가 표시된다.    </p><p><img src="/images/blockchainEvents/buyerDashboard.png" alt="buyerDashboard">    </p><p><img src="/images/blockchainEvents/sellerDashboard.png" alt="sellerDashboard">    </p><h4 id="경매-종료"><a href="#경매-종료" class="headerlink" title="경매 종료"></a>경매 종료</h4><p> <code>POST /StartBidding</code>을 통해 경매를 시작하였다면, 경매 종료는 <code>POST /CloseBidding</code>을 이용한다.</p><figure class="highlight json"><figcaption><span>POST /CloseBidding</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.CloseBidding"</span>,</span><br><span class="line">  <span class="attr">"listing"</span>: <span class="string">"sampleListingId"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>경매가 종료되면 최고금액인 300을 입찰한 <code>memberB</code>가 낙찰받게 되며 이 정보는 노드 서버의 이벤트 리스너에 의해 <a href="http://localhost:8000/buyer.html" target="_blank" rel="noopener">http://localhost:8000/buyer.html</a>, <a href="http://localhost:8000/seller.html" target="_blank" rel="noopener">http://localhost:8000/seller.html</a> 의 UI에 자동으로 업데이트된다.    </p><p><img src="/images/blockchainEvents/buyer_ui.png" alt="buyer_ui">    </p><p><img src="/images/blockchainEvents/seller_ui.png" alt="seller_ui"></p>]]></content:encoded>
      
      <comments>https://j-s-lee.github.io/2018/08/27/product-auction-network-with-events/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Hyperledger Composer - 상품 경매 네트워크</title>
      <link>https://j-s-lee.github.io/2018/08/22/product-auction-network/</link>
      <guid>https://j-s-lee.github.io/2018/08/22/product-auction-network/</guid>
      <pubDate>Wed, 22 Aug 2018 06:26:39 GMT</pubDate>
      <description>
      
        &lt;p&gt;&lt;a href=&quot;https://github.com/IBM/BlockchainSmartContractTrading-CompositeJourney&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Hyperledger Composer Composite Journey&lt;/a&gt; Part 2 데모 실습 내용을 정리한 글이다.&lt;/p&gt;
&lt;p&gt;Part 2는 하이퍼레저 컴포저를 사용하여 간단한 경매 네트워크를 실습해 보는 과정이다.&lt;/p&gt;
&lt;p&gt;앞선 튜토리얼과 유사하지만 판매자와 입찰자 권한을 나누고, 각 권한에 맞는 트랜잭션을 submit 할 수 있다. 판매자는 상품을 등록한 후에 경매를 시작하고, 각 입찰 참여자들은 경매 원하는 입찰가를 포함하는 트랜잭션을 발생시킨다.&lt;/p&gt;
&lt;p&gt;최종적으로 판매자가 경매를 종료하면 최고 입찰가를 제출한 입찰자의 잔액이 작성했던 입찰가 만큼 줄어들고 상품 소유자가 되며, 판매자는 입찰가만큼 잔액이 증가한다. 즉, 별도의 중개인이 없이 판매자와 입찰자간의 거래가 성사되는 것이다. &lt;/p&gt;
      
      </description>
      
      <content:encoded><![CDATA[<p><a href="https://github.com/IBM/BlockchainSmartContractTrading-CompositeJourney" target="_blank" rel="noopener">Hyperledger Composer Composite Journey</a> Part 2 데모 실습 내용을 정리한 글이다.</p><p>Part 2는 하이퍼레저 컴포저를 사용하여 간단한 경매 네트워크를 실습해 보는 과정이다.</p><p>앞선 튜토리얼과 유사하지만 판매자와 입찰자 권한을 나누고, 각 권한에 맞는 트랜잭션을 submit 할 수 있다. 판매자는 상품을 등록한 후에 경매를 시작하고, 각 입찰 참여자들은 경매 원하는 입찰가를 포함하는 트랜잭션을 발생시킨다.</p><p>최종적으로 판매자가 경매를 종료하면 최고 입찰가를 제출한 입찰자의 잔액이 작성했던 입찰가 만큼 줄어들고 상품 소유자가 되며, 판매자는 입찰가만큼 잔액이 증가한다. 즉, 별도의 중개인이 없이 판매자와 입찰자간의 거래가 성사되는 것이다. </p><a id="more"></a><p>공식 사이트에서 쿼리 튜토리얼을 보기 전에 한글로 정리된 예제를 한두개 더 보는게 내용 정리하는데 도움이 될 것 같아 검색을 하다 발견한 데모인데 이렇게 한글로 잘 설명된 가이드를 찾게 되서 다행이다!!</p><!--toc--><h2 id="아카이브-생성"><a href="#아카이브-생성" class="headerlink" title="아카이브 생성"></a>아카이브 생성</h2><p>하이퍼레저 컴포저 개발 툴 설치 후 저장소를 복제한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/IBM/BlockchainSmartContractTrading-CompositeJourney.git</span><br></pre></td></tr></table></figure><p> 저장소에서 복제한 디렉토리로 이동 후 다음 명령을 사용하여 네트워크 아카이브(.bna)를 생성한다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install</span><br></pre></td></tr></table></figure><p>명령을 실행하면 아래와 같은 결과가 나온다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&gt; mkdirp ./dist &amp;&amp; composer archive create --sourceType dir --sourceName . -a ./dist/product-auction.bna</span><br><span class="line"></span><br><span class="line">Creating Business Network Archive</span><br><span class="line"></span><br><span class="line">Looking <span class="keyword">for</span> package.json of Business Network Definition</span><br><span class="line">Input directory: /Users/LeeJaeSeok/demo/BlockchainSmartContractTrading-CompositeJourney</span><br><span class="line"></span><br><span class="line">Found:</span><br><span class="line">Description: Sample product auction network</span><br><span class="line">Name: product-auction</span><br><span class="line">Identifier: product-auction@0.0.1</span><br><span class="line"></span><br><span class="line">Written Business Network Definition Archive file to</span><br><span class="line">Output file: ./dist/product-auction.bna</span><br><span class="line"></span><br><span class="line">Command succeeded</span><br></pre></td></tr></table></figure><p><code>composer archive create</code> 명령을 통해 <code>dist</code> 폴더에 <code>product-auction.bna</code> 파일이 생성되었다.</p><p>프로젝트 디렉토리 내에는 <code>dist</code> 폴더 외에도 <code>test</code>  폴더에 <code>productAuction.js</code> 라는 비즈니스 네트워크를 테스트 할 수 있는 스크립트가 있다.</p><p>이 테스트 스크립트는 프로젝트 디렉토리에서 아래 명령을 통해 실행 할 수 있다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm <span class="built_in">test</span></span><br></pre></td></tr></table></figure><p>이 명령은 아래와 같이 Node.js의 테스트 프레임워크인 <a href="https://mochajs.org" target="_blank" rel="noopener">Mocha</a>를 통해  현재 경로의 <code>test/</code>디렉토리에 있는 모든 <code>.js</code>파일의 테스트를 진행한다:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&gt; product-auction@0.0.1 <span class="built_in">test</span> C:\Users\LeeJaeSeok\demo\BlockchainSmartContractTrading-CompositeJourney</span><br><span class="line">&gt; nyc mocha -t 0 <span class="built_in">test</span>/*.js</span><br><span class="line"></span><br><span class="line"><span class="comment">#org.acme.product.auction</span></span><br><span class="line">  √ Authorized owner should start the bidding (75ms)</span><br><span class="line">  √ Members bid <span class="keyword">for</span> the product (199ms)</span><br><span class="line">  √ Close bid <span class="keyword">for</span> the product (243ms)</span><br><span class="line">  </span><br><span class="line">3 passing (4s)</span><br><span class="line"></span><br><span class="line">...</span><br></pre></td></tr></table></figure><h2 id="컴포저-플레이그라운드를-이용한-경매-네트워크-데모"><a href="#컴포저-플레이그라운드를-이용한-경매-네트워크-데모" class="headerlink" title="컴포저 플레이그라운드를 이용한 경매 네트워크 데모"></a>컴포저 플레이그라운드를 이용한 경매 네트워크 데모</h2><p><a href="https://composer-playground.mybluemix.net" target="_blank" rel="noopener">플레이그라운드</a>를 열어 <code>product-auction.bna</code> 파일을 배포한다.</p><p>이전에 플레이그라운드를 사용한 적이 있다면, 웹브라우저 콘솔에서 <code>localStorage.clear()</code>를 사용해 웹브라우저 로컬 저장소를 지운다.    </p><h3 id="참여자-생성"><a href="#참여자-생성" class="headerlink" title="참여자 생성"></a>참여자 생성</h3><p><strong>Test</strong> 탭에서 비즈니스 네트워크를 테스트 하려면:</p><p>PARTICIPANTS &gt; Seller 에 새 참여자를 생성한다.</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Seller"</span>,</span><br><span class="line">    <span class="attr">"organisation"</span>: <span class="string">"ACME"</span>,</span><br><span class="line">    <span class="attr">"email"</span>: <span class="string">"auction@acme.org"</span>,</span><br><span class="line">    <span class="attr">"balance"</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="attr">"products"</span>: []</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>PARTICIPANTS &gt; Member 에는 다음의 두명의 참여자를 생성한다.</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Member"</span>,</span><br><span class="line">    <span class="attr">"firstName"</span>: <span class="string">"Amy"</span>,</span><br><span class="line">    <span class="attr">"lastName"</span>: <span class="string">"Williams"</span>,</span><br><span class="line">    <span class="attr">"email"</span>: <span class="string">"memberA@acme.org"</span>,</span><br><span class="line">    <span class="attr">"balance"</span>: <span class="number">1000</span>,</span><br><span class="line">    <span class="attr">"products"</span>: []</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Member"</span>,</span><br><span class="line">    <span class="attr">"firstName"</span>: <span class="string">"Billy"</span>,</span><br><span class="line">    <span class="attr">"lastName"</span>: <span class="string">"Thompson"</span>,</span><br><span class="line">    <span class="attr">"email"</span>: <span class="string">"memberB@acme.org"</span>,</span><br><span class="line">    <span class="attr">"balance"</span>: <span class="number">1000</span>,</span><br><span class="line">    <span class="attr">"products"</span>: []</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>이제 <code>admin</code> 탭을 클릭하여 새로운 ID를 생성한다.    </p><p>참고한 가이드에는 <code>ID생성</code> &gt; <code>월렛에 추가</code> 하는 방식으로 설명되어 있는데 컴포저나 플레이그라운드 버전이 바뀌면서 변경된 것인지 ID 생성과 함께 월렛에 추가되었다는 notification을 볼 수 있어 별도 월렛 추가 과정은 필요하지 않았다.</p><p><img src="/images/capture/add_seller_id.png" alt="add_seller_id">  </p><p>ID 추가에는 위 화면과 같이 <code>ID NAME</code>과 <code>Participant</code>가 필요하다. 앞에서 생성한 1개의 <code>seller</code> 정보와 <code>memberA</code>, <code>memberB</code>의 정보를 이용하여 3개의 ID를 생성한다.</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ID NAME : seller</span><br><span class="line">Participant : resource:org<span class="selector-class">.acme</span><span class="selector-class">.product</span><span class="selector-class">.auction</span><span class="selector-class">.Seller</span>#auction@acme.org</span><br></pre></td></tr></table></figure><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ID NAME : memberA</span><br><span class="line">Participant : resource:org<span class="selector-class">.acme</span><span class="selector-class">.product</span><span class="selector-class">.auction</span><span class="selector-class">.Member</span>#memberA@acme.org</span><br></pre></td></tr></table></figure><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ID NAME : memberB</span><br><span class="line">Participant : resource:org<span class="selector-class">.acme</span><span class="selector-class">.product</span><span class="selector-class">.auction</span><span class="selector-class">.Member</span>#memberB@acme.org</span><br></pre></td></tr></table></figure><h3 id="상품-등록-및-경매-시작"><a href="#상품-등록-및-경매-시작" class="headerlink" title="상품 등록 및 경매 시작"></a>상품 등록 및 경매 시작</h3><p>ID 생성 후 <code>seller</code>를 사용하도록 선택하고 <code>test</code> 탭으로 이동하여 <code>Submit Transaction</code>을 클릭하여  <code>AddProduct</code> 및 <code>StartBidding</code> 트랜잭션을 수행한다.  </p><p><img src="/images/capture/use_seller_id.png" alt="use_seller_id"></p><p><img src="/images/capture/addProduct.png" alt="addProduct"></p><p><code>owner</code>에는 <code>seller ID</code> 생성시 입력한 <code>participant</code> 정보를 입력하면 된다.</p><p>참고한 가이드에는 JSON Data에 <code>productId</code>는 없는데 원하는 값을 입력하거나 팝업 하단의 <code>Generate Random Data</code>를 클릭하면 자동으로 값이 채워진다.</p><p>이 버튼을 이용할 경우 다음에 수행할 <code>StartBidding</code> 트랜잭션에 사용하기 위해 <code>productId</code>값을 복사해 두는 것이 좋다.  </p><p><code>StartBidding</code> 트랜잭션도 가이드에서는 <code>listingId</code>값에 대한 설명이 언급되지 않지만 임의의 값이 필요하다.</p><p>JSON Data의 <code>product</code> 에는 위에서 복사해 둔 <code>productId</code>값이 사용되며, <code>resource:org.acme.product.auction.Product#&lt;productId&gt;</code> 의 형태로 입력하면 된다.</p><p><code>reservePrice</code>는 경매 예상가격이다.</p><p><img src="/images/capture/startBidding.png" alt="startBidding"></p><p><code>seller</code>는 이 두 트랜잭션을 통해 상품을 경매에 등록한 것이다. <code>Test</code> 탭의 <code>ProductListing</code>에서 상품 리스트를 볼 수 있다.    </p><h3 id="경매-입찰"><a href="#경매-입찰" class="headerlink" title="경매 입찰"></a>경매 입찰</h3><p>이제 <code>Member</code>에 속하는 <code>memberA</code>와 <code>memberB</code>는 경매에 참여하기 위해 <code>Offer</code> 트랜잭션을 submit할 수 있다.  </p><p>각각 ID 리스트에서 <code>member ID</code> 를 선택하고 <code>Submit Transaction</code> 버튼을 클릭하여 경매에 참여한다.</p><p><img src="/images/capture/memberA_Offer.png" alt="memberA_Offer"></p><p>테스트를 위해 아래와 같이 경매 입찰가격을 다르게 하여 <code>memberA</code> 와 <code>memberB</code>가 <code>Offer</code> 트랜잭션을 submit했다.</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">// memberA</span><br><span class="line">&#123;</span><br><span class="line">    <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Offer"</span>,</span><br><span class="line">    "bidPrice": 50, // 경매 입찰가</span><br><span class="line">    "listing": "resource:org.acme.product.auction.ProductListing#&lt;ListingId&gt;", // ProductListing에서의 listingId</span><br><span class="line">    "member": "resource:org.acme.product.auction.Member#memberA@acme.org"</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">// memberB</span><br><span class="line">&#123;</span><br><span class="line">    <span class="attr">"$class"</span>: <span class="string">"org.acme.product.auction.Offer"</span>,</span><br><span class="line">    "bidPrice": 100, // 경매 입찰가</span><br><span class="line">    "listing": "resource:org.acme.product.auction.ProductListing#&lt;ListingId&gt;", // ProductListing에서의 listingId</span><br><span class="line">    "member": "resource:org.acme.product.auction.Member#memberB@acme.org"</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>ProductListing</code> 에서 모든 입찰 내역을 확인 할  수 있다.</p><p><code>offers</code>에는 경매에 참여한 모든 입찰자들의 입찰정보가 포함된다.</p><p><img src="/images/capture/productListing_after_offer.png" alt="productListing_after_offer">    </p><h3 id="경매-종료"><a href="#경매-종료" class="headerlink" title="경매 종료"></a>경매 종료</h3><p>이제 다시 <code>seller ID</code>를 선택하여 <code>CloseBidding</code> 트랜잭션을 통해 경매를 종료시킨다.</p><p>트랜잭션 JSON Data 내용은 위의 <code>StartBidding</code> 트랜잭션 JSON Data 입력하는 방법을 참고하면 쉽게 작성할 수 있다.    </p><p>경매 종료 후 <code>ProductListing</code>으로 이동하면 아래와 같이 상품의 판매상태가 <code>FOR_SALE</code> 에서 <code>SOLD</code>로 변경된 것을 확인할 수 있다.</p><p><img src="/images/capture/productListing_after_closebidding.png" alt="productListing_after_closebidding"></p><p><code>Product</code>에서 판매된 상품의 <code>owner</code>가 경매 최고입찰가를 제시한  <code>memberB</code>로 변경된 것을 확인할 수 있다.</p><p><img src="/images/capture/product_owner_changed.png" alt="product_owner_changed"></p><p><code>Member</code>를 보면  <code>memberB</code>의 잔액(<code>balance</code>)이 입찰가인 <code>100</code> 만큼 줄어들었고 <code>products</code>에 구매한 상품이 추가된 것을 볼 수 있다.    </p><p><img src="/images/capture/memberB_after_bidding.png" alt="memberB_after_bidding"></p>]]></content:encoded>
      
      <comments>https://j-s-lee.github.io/2018/08/22/product-auction-network/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Hyperledger Developer Tutorial</title>
      <link>https://j-s-lee.github.io/2018/08/21/hyperledger-developer-tutorial/</link>
      <guid>https://j-s-lee.github.io/2018/08/21/hyperledger-developer-tutorial/</guid>
      <pubDate>Tue, 21 Aug 2018 02:13:17 GMT</pubDate>
      <description>
      
        &lt;p&gt;Hyperledger Composer 개발 환경 셋업이 끝난 후 간단한 튜토리얼을 진행해 보았다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;튜토리얼 가이드 :  &lt;a href=&quot;https://hyperledger.github.io/composer/latest/tutorials/developer-tutorial.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Developer tutorial for creating a Hyperledger Composer solution&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;!--toc--&gt;
&lt;h2 id=&quot;Prerequisites&quot;&gt;&lt;a href=&quot;#Prerequisites&quot; class=&quot;headerlink&quot; title=&quot;Prerequisites&quot;&gt;&lt;/a&gt;Prerequisites&lt;/h2&gt;&lt;p&gt;이 튜토리얼은 &lt;a href=&quot;https://hyperledger.github.io/composer/latest/installing/development-tools.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;개발 환경 설치&lt;/a&gt;가 완료된 후 진행하였으며, 에디터는 VSCode를 사용했다.  &lt;/p&gt;
&lt;h2 id=&quot;Skeleton-Business-Network-생성&quot;&gt;&lt;a href=&quot;#Skeleton-Business-Network-생성&quot; class=&quot;headerlink&quot; title=&quot;Skeleton Business Network 생성&quot;&gt;&lt;/a&gt;Skeleton Business Network 생성&lt;/h2&gt;&lt;p&gt;앞서 설치한 Yeoman generator를 이용해 스켈레톤 비즈니스 네트워크를 생성한다. Yeoman을 이용하면 비즈니스 네트워크에 필요한 컴포넌트들을 포함한 디렉토리를 생성해준다.&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;$ yo hyperledger-composer:businessnetwork&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
      
      </description>
      
      <content:encoded><![CDATA[<p>Hyperledger Composer 개발 환경 셋업이 끝난 후 간단한 튜토리얼을 진행해 보았다.</p><ul><li>튜토리얼 가이드 :  <a href="https://hyperledger.github.io/composer/latest/tutorials/developer-tutorial.html" target="_blank" rel="noopener">Developer tutorial for creating a Hyperledger Composer solution</a> </li></ul><!--toc--><h2 id="Prerequisites"><a href="#Prerequisites" class="headerlink" title="Prerequisites"></a>Prerequisites</h2><p>이 튜토리얼은 <a href="https://hyperledger.github.io/composer/latest/installing/development-tools.html" target="_blank" rel="noopener">개발 환경 설치</a>가 완료된 후 진행하였으며, 에디터는 VSCode를 사용했다.  </p><h2 id="Skeleton-Business-Network-생성"><a href="#Skeleton-Business-Network-생성" class="headerlink" title="Skeleton Business Network 생성"></a>Skeleton Business Network 생성</h2><p>앞서 설치한 Yeoman generator를 이용해 스켈레톤 비즈니스 네트워크를 생성한다. Yeoman을 이용하면 비즈니스 네트워크에 필요한 컴포넌트들을 포함한 디렉토리를 생성해준다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ yo hyperledger-composer:businessnetwork</span><br></pre></td></tr></table></figure><a id="more"></a><p><img src="/images/tutorialNetwork/generate_businessnetwork.png" alt="generate_businessnetwork">  </p><h2 id="비즈니스-네트워크-정의"><a href="#비즈니스-네트워크-정의" class="headerlink" title="비즈니스 네트워크 정의"></a>비즈니스 네트워크 정의</h2><p>위에서 생성한 스켈레톤 비즈니스 네트워크는 다음의 파일들로 구성된다.</p><ul><li>모델(<code>.cto</code>) - 자산(assets), 참가자(participants), 트랜잭션(transactions)에 대한 클래스 정의</li><li>스크립트(<code>logic.js</code>) - 트랜잭션 프로세서 function</li><li>엑세스컨트롤(<code>permissions.acl</code>) - 권한 제어 규칙</li><li>JSON(<code>package.json</code>) - 비즈니스 네트워크 메타데이터  </li></ul><h3 id="모델-파일-수정"><a href="#모델-파일-수정" class="headerlink" title="모델 파일 수정"></a>모델 파일 수정</h3><p>assets, participants, transactions의 클래스 정의를 위해 모델 파일을 아래와 같이 수정한다.</p><figure class="highlight javascript"><figcaption><span>models/org.example.mynetwork.cto</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> * My commodity trading network</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">namespace org.example.mynetwork</span><br><span class="line">asset Commodity identified by tradingSymbol &#123;</span><br><span class="line">    o <span class="built_in">String</span> tradingSymbol</span><br><span class="line">    o <span class="built_in">String</span> description</span><br><span class="line">    o <span class="built_in">String</span> mainExchange</span><br><span class="line">    o Double quantity</span><br><span class="line">    --&gt; Trader owner</span><br><span class="line">&#125;</span><br><span class="line">participant Trader identified by tradeId &#123;</span><br><span class="line">    o <span class="built_in">String</span> tradeId</span><br><span class="line">    o <span class="built_in">String</span> firstName</span><br><span class="line">    o <span class="built_in">String</span> lastName</span><br><span class="line">&#125;</span><br><span class="line">transaction Trade &#123;</span><br><span class="line">    --&gt; Commodity commodity</span><br><span class="line">    --&gt; Trader newOwner</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="트랜잭션-로직-스크립트-수정"><a href="#트랜잭션-로직-스크립트-수정" class="headerlink" title="트랜잭션 로직 스크립트 수정"></a>트랜잭션 로직 스크립트 수정</h3><p><code>3-1</code>에서 정의한 <code>Trade</code> 트랜잭션이 실행할 자바스크립트 로직을 로직 스크립트에 추가한다.</p><figure class="highlight javascript"><figcaption><span>logic.js</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> * Track the trade of a commodity from one trader to another</span></span><br><span class="line"><span class="comment"> * @param &#123;org.example.mynetwork.Trade&#125; trade - the trade to be processed</span></span><br><span class="line"><span class="comment"> * @transaction</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">tradeCommodity</span>(<span class="params">trade</span>) </span>&#123;</span><br><span class="line">    trade.commodity.owner = trade.newOwner;</span><br><span class="line">    <span class="keyword">let</span> assetRegistry = <span class="keyword">await</span> getAssetRegistry(<span class="string">'org.example.mynetwork.Commodity'</span>);</span><br><span class="line">    <span class="keyword">await</span> assetRegistry.update(trade.commodity);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br></pre></td></tr></table></figure><h3 id="access-control-규칙-수정"><a href="#access-control-규칙-수정" class="headerlink" title="access control 규칙 수정"></a>access control 규칙 수정</h3><figure class="highlight javascript"><figcaption><span>permissions.acl</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> * Access control rules for tutorial-network</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">rule Default &#123;</span><br><span class="line">    description: <span class="string">"Allow all participants access to all resources"</span></span><br><span class="line">    participant: <span class="string">"ANY"</span></span><br><span class="line">    operation: ALL</span><br><span class="line">    resource: <span class="string">"org.example.mynetwork.*"</span></span><br><span class="line">    action: ALLOW</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">rule SystemACL &#123;</span><br><span class="line">  description:  <span class="string">"System ACL to permit all access"</span></span><br><span class="line">  participant: <span class="string">"ANY"</span></span><br><span class="line">  operation: ALL</span><br><span class="line">  resource: <span class="string">"org.hyperledger.composer.system.**"</span></span><br><span class="line">  action: ALLOW</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="아카이브-생성"><a href="#아카이브-생성" class="headerlink" title="아카이브 생성"></a>아카이브 생성</h2><p>정의된 비즈니스 네트워크를 배포하기 위해서는 비즈니스 네트워크 아카이브(<code>.bna</code>)파일로 패키지화 되어야 한다.</p><p><code>tutorial-network</code> 디렉토리로 이동한 후 아래 명령어를 수행한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer archive create -t dir -n .</span><br></pre></td></tr></table></figure><p>커맨드가 실행되면 디렉토리 내에  <a href="mailto:`tutorial-network@0.0.1.bna" target="_blank" rel="noopener">`tutorial-network@0.0.1.bna</a>` 와 같이 아카이브 파일이 생성된다.  </p><h2 id="비즈니스-네트워크-배포"><a href="#비즈니스-네트워크-배포" class="headerlink" title="비즈니스 네트워크 배포"></a>비즈니스 네트워크 배포</h2><p>생성된 <code>.bna</code> 파일은 <code>composer network install</code>명령을 통해 Hyperledger Fabric 인스턴스에 배포할 수 있다.</p><p>이 명령을 사용하려면 <code>PeerAdmin</code> 비즈니스 네트워크 카드가 필요하지만 개발 환경 설치 과정에서 이미 생성된 것이 있다.</p><ol><li><p>비즈니스 네트워크 설치를 위해 <code>tutorial-network</code>로 이동해서 아래 명령을 실행한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna</span><br></pre></td></tr></table></figure><p><code>composer network install</code> 명령을 사용하려면 PeerAdmin  비즈니스 네트워크 카드, 비즈니스 네트워크가 정의된 <code>.bna</code>파일의 경로가 필요하다.  </p></li></ol><ol start="2"><li><p>설치한 컴포저 네트워크는 <code>composer network start</code> 명령을 통해 실행할 수 있다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card</span><br></pre></td></tr></table></figure></li><li><p>사용 가능한 비즈니스 네트워크 카드로 네트워크 관리자 ID를 가져오려면 <code>composer network start</code> 명령에서 지정한 파일명을 이용해 다음 명령을 실행하면 된다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer card import --file networkadmin.card</span><br></pre></td></tr></table></figure></li><li><p>아래 명령을 입력하면 비즈니스 네트워크가 성공적으로 배포되었는지 확인할 수 있다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer network ping --card admin@tutorial-network</span><br></pre></td></tr></table></figure></li></ol><h2 id="REST-서버-생성"><a href="#REST-서버-생성" class="headerlink" title="REST 서버 생성"></a>REST 서버 생성</h2><p>Hyperledger Composer는 배포된 비즈니스 네트워크 기반의 REST API 서버를 생성 할 수 있다.</p><p><code>tutorial-network</code> 디렉토리로 이동 후 <code>composer-rest-server</code> 명령을 입력한 후 REST API 생성 방법을 설정한다.</p><p><img src="/images/tutorialNetwork/generate_rest_api_server.png" alt="generate_rest_api_server"></p><p>composer-rest-server가 성공적으로 시작되었다면 <a href="http://localhost:3000/explorer" target="_blank" rel="noopener">http://localhost:3000/explorer</a> 로 이동하면 아래와 같은 웹브라우저 화면을 볼 수 있다.</p><p><img src="/images/tutorialNetwork/composer_rest_server.png" alt="composer_rest_server"></p><h2 id="어플리케이션-생성"><a href="#어플리케이션-생성" class="headerlink" title="어플리케이션 생성"></a>어플리케이션 생성</h2><p>Hyperledger Composer는 REST API를 이용하는 Angular 어플리케이션 생성도 가능하다.</p><p><code>tutorial-network</code> 디렉토리에서 <code>yo hyperledger-composer:angular</code> 명령어를 실행하면 된다.</p><p><img src="/images/tutorialNetwork/generate_angular_app.png" alt="generate_angular_app">  </p><p>어플리케이션 생성이 성공적으로 완료되면 아래와 같은 메시지를 볼 수 있다.</p><p><img src="/images/tutorialNetwork/generated_angular_app.png" alt="generated_angular_app">  </p><p><code>npm install</code> 후 <code>npm start</code>를 실행하면 어플리케이션이 실행된다.</p><p><code>npm start</code> 명령은 해당 어플리케이션의 <strong>package.json</strong>의 scripts에 있는 start 명령어를 실행한다.  </p><p><img src="/images/tutorialNetwork/running_angular_app.png" alt="running_angular_app">  </p><p><img src="/images/tutorialNetwork/angular_app.png" alt="angular_app">  </p><p>웹브라우저를 통해 <a href="http://localhost:4200" target="_blank" rel="noopener">http://localhost:4200</a> 로 이동하면 어플리케이션이 생성 된 것을 볼 수 있다.  </p>]]></content:encoded>
      
      <comments>https://j-s-lee.github.io/2018/08/21/hyperledger-developer-tutorial/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Docker &amp; Docker Compose 버전 업그레이드</title>
      <link>https://j-s-lee.github.io/2018/08/17/hyperledger-error-log2/</link>
      <guid>https://j-s-lee.github.io/2018/08/17/hyperledger-error-log2/</guid>
      <pubDate>Fri, 17 Aug 2018 07:21:04 GMT</pubDate>
      <description>
      
        &lt;p&gt;&lt;a href=&quot;https://hyperledger.github.io/composer/latest/installing/development-tools.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Hyperledger Composer Installing 가이드&lt;/a&gt;의 절차에 따라 Hyperledger Fabric을 설치한 후 &lt;code&gt;./startFabric.sh&lt;/code&gt; 스크립트를 실행하면 &lt;code&gt;No such command: down&lt;/code&gt; 오류가 발생하는 경우가 있다.&lt;/p&gt;
&lt;p&gt; &lt;code&gt;docker&lt;/code&gt;와 &lt;code&gt;docker-compose&lt;/code&gt; 의 버전 문제였는데.. &lt;a href=&quot;https://j-s-lee.github.io/2018/08/11/getting-started-hyperledger-with-windows10-wsl/&quot;&gt;Hyperledger Composer &amp;amp; Fabric 설치에 필요한 사전 요구사항&lt;/a&gt;에 표기된 버전을 참고하여 설치되어 있는 버전이 낮을 경우 업그레이드 해줘야 한다.&lt;/p&gt;
      
      </description>
      
      <content:encoded><![CDATA[<p><a href="https://hyperledger.github.io/composer/latest/installing/development-tools.html" target="_blank" rel="noopener">Hyperledger Composer Installing 가이드</a>의 절차에 따라 Hyperledger Fabric을 설치한 후 <code>./startFabric.sh</code> 스크립트를 실행하면 <code>No such command: down</code> 오류가 발생하는 경우가 있다.</p><p> <code>docker</code>와 <code>docker-compose</code> 의 버전 문제였는데.. <a href="https://j-s-lee.github.io/2018/08/11/getting-started-hyperledger-with-windows10-wsl/">Hyperledger Composer &amp; Fabric 설치에 필요한 사전 요구사항</a>에 표기된 버전을 참고하여 설치되어 있는 버전이 낮을 경우 업그레이드 해줘야 한다.</p><a id="more"></a><p>검색해 보니  <code>docker-compose</code>의 경우 설치된 <code>docker</code> 버전에 따라 설치 가능한 latest 버전에 제한이 있는 것 같다.</p><p><code>$ docker -v</code> , <code>$ docker-compose -v</code> 명령을 통해 각각의 버전을 확인 후 최신 버전으로 업그레이드가 필요한 경우 다음의 커맨드를 이용하여 업그레이드가 가능하다.</p><ul><li>docker upgrade</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apt-get update</span><br><span class="line">$ sudo apt-get upgrade</span><br></pre></td></tr></table></figure><ul><li>docker-compose upgrade</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apt-get -y install python-pip</span><br><span class="line">$ sudo pip install --upgrade pip setuptools docker-compose</span><br></pre></td></tr></table></figure><p>업그레이드 이후 다시 <code>./startFabric.sh</code> 스크립트를 실행 시키고  <code>docker ps</code> 를 통해 컨테이너 상태를 확인 할 수 있었다.  </p>]]></content:encoded>
      
      <comments>https://j-s-lee.github.io/2018/08/17/hyperledger-error-log2/#disqus_thread</comments>
    </item>
    
    <item>
      <title>NPM global install error with Yeoman</title>
      <link>https://j-s-lee.github.io/2018/08/17/hyperledger-devtools-installing-error-log/</link>
      <guid>https://j-s-lee.github.io/2018/08/17/hyperledger-devtools-installing-error-log/</guid>
      <pubDate>Fri, 17 Aug 2018 02:16:57 GMT</pubDate>
      <description>
      
        &lt;p&gt;Hyperledger composer 개발 환경 설정 중 발생한 에러들 정리&lt;/p&gt;
      
      </description>
      
      <content:encoded><![CDATA[<p>Hyperledger composer 개발 환경 설정 중 발생한 에러들 정리</p><a id="more"></a><h2 id="Yeoman-설치"><a href="#Yeoman-설치" class="headerlink" title="Yeoman 설치"></a>Yeoman 설치</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g yo</span><br></pre></td></tr></table></figure><h3 id="1-global-installation을-위한-NPM-default-directory-생성"><a href="#1-global-installation을-위한-NPM-default-directory-생성" class="headerlink" title="1. global installation을 위한 NPM default directory 생성"></a>1. global installation을 위한 NPM default directory 생성</h3><p>우선 Permission 문제에 대한 문서 <a href="https://docs.npmjs.com/getting-started/fixing-npm-permissions" target="_blank" rel="noopener">NPM docs - getting-started - fixing-npm-permissions</a> 를 참고하여 npm의 <code>Default Directory</code>를 수정한다.</p><ol><li>global installation을 위한 디렉토리 생성</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir ~/.npm-global</span><br></pre></td></tr></table></figure><ol start="2"><li>디렉토리 경로를 <code>npm config</code>에  세팅</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ npm config <span class="built_in">set</span> prefix <span class="string">'~/.npm-global'</span></span><br><span class="line">$ npm config get prefix <span class="comment"># config prefix 세팅이 잘 되었는지 확인</span></span><br></pre></td></tr></table></figure><ol start="3"><li>환경변수 설정</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ vi ~/.profile <span class="comment"># .profile 수정(사용하는 에디터에 따라 명령어가 다를 수 있다)</span></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">export</span> PATH=~/.npm-global/bin:<span class="variable">$PATH</span> <span class="comment"># 위에서 생성한 npm global install을 위한 dir경로</span></span><br></pre></td></tr></table></figure><p><code>.profile</code> 수정 후에는 변경사항을 적용시켜야 한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">source</span> ~/.profile</span><br></pre></td></tr></table></figure><h3 id="2-디렉토리-권한-수정"><a href="#2-디렉토리-권한-수정" class="headerlink" title="2. 디렉토리 권한 수정"></a>2. 디렉토리 권한 수정</h3><p>1번의 과정을 거친 후에도 다시 <code>npm install -g yo</code> 실행 시 아래와 같은 오류 발생</p><p>오류 내용이 길어서 전체 내용 확인이 필요한 경우 에러 내용에 명시된 로그파일 <code>/home/hyper/.npm/_logs/2018-08-17T02_14_30_188Z-debug.log</code>을 통해 확인할 수 있다.</p><ol><li>에러 로그</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">npm WARN checkPermissions Missing write access to /home/hyper/.npm-global/lib/node_modules/yo</span><br><span class="line">npm WARN checkPermissions Missing write access to /home/hyper/.npm-global/lib/node_modules/yo/node_modules</span><br><span class="line">npm ERR! path /home/hyper/.npm-global/lib/node_modules/yo</span><br><span class="line">npm ERR! code EACCES</span><br><span class="line">npm ERR! errno -13</span><br><span class="line">npm ERR! syscall access</span><br><span class="line">npm ERR! Error: EACCES: permission denied, access <span class="string">'/home/hyper/.npm-global/lib/node_modules/yo'</span></span><br><span class="line">npm ERR!  &#123; Error: EACCES: permission denied, access <span class="string">'/home/hyper/.npm-global/lib/node_modules/yo'</span></span><br><span class="line">npm ERR!   stack: <span class="string">'Error: EACCES: permission denied, access \'</span>/home/hyper/.npm-global/lib/node_modules/yo\<span class="string">''</span>,</span><br><span class="line">npm ERR!   errno: -13,</span><br><span class="line">npm ERR!   code: <span class="string">'EACCES'</span>,</span><br><span class="line">npm ERR!   syscall: <span class="string">'access'</span>,</span><br><span class="line">npm ERR!   path: <span class="string">'/home/hyper/.npm-global/lib/node_modules/yo'</span> &#125;</span><br><span class="line">npm ERR!</span><br><span class="line">npm ERR! The operation was rejected by your operating system.</span><br><span class="line">npm ERR! It is likely you <span class="keyword">do</span> not have the permissions to access this file as the current user</span><br><span class="line">npm ERR!</span><br><span class="line">npm ERR! If you believe this might be a permissions issue, please double-check the</span><br><span class="line">npm ERR! permissions of the file and its containing directories, or try running</span><br><span class="line">npm ERR! the <span class="built_in">command</span> again as root/Administrator (though this is not recommended).</span><br><span class="line"></span><br><span class="line">npm ERR! A complete <span class="built_in">log</span> of this run can be found <span class="keyword">in</span>:</span><br><span class="line">npm ERR!     /home/hyper/.npm/_logs/2018-08-17T02_14_30_188Z-debug.log</span><br></pre></td></tr></table></figure><ol start="2"><li>에러 로그에 명시된 access 오류가 발생하는 디렉토리 권한 수정</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo chown -R hyper /home/hyper/.npm-global</span><br><span class="line">$ npm cache clean -f</span><br><span class="line">npm WARN using --force I sure hope you know what you are doing.</span><br></pre></td></tr></table></figure><ol start="3"><li>Yeoman 설치</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g yo</span><br><span class="line">/home/hyper/.npm-global/bin/yo -&gt; /home/hyper/.npm-global/lib/node_modules/yo/lib/cli.js</span><br><span class="line">/home/hyper/.npm-global/bin/yo-complete -&gt; /home/hyper/.npm-global/lib/node_modules/yo/lib/completion/index.js</span><br><span class="line"></span><br><span class="line">&gt; yo@2.0.5 postinstall /home/hyper/.npm-global/lib/node_modules/yo</span><br><span class="line">&gt; yodoctor</span><br><span class="line"></span><br><span class="line">Yeoman Doctor</span><br><span class="line">Running sanity checks on your system</span><br><span class="line"></span><br><span class="line">✔ Global configuration file is valid</span><br><span class="line">✔ NODE_PATH matches the npm root</span><br><span class="line">✔ Node.js version</span><br><span class="line">✔ No .bowerrc file <span class="keyword">in</span> home directory</span><br><span class="line">✔ No .yo-rc.json file <span class="keyword">in</span> home directory</span><br><span class="line">✔ npm version</span><br><span class="line">✔ yo version</span><br><span class="line"></span><br><span class="line">Everything looks all right!</span><br><span class="line">+ yo@2.0.5</span><br><span class="line">removed 1 package and updated 6 packages <span class="keyword">in</span> 27.231s</span><br><span class="line">hyper@DESKTOP-BOKQP6N:~$</span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      <comments>https://j-s-lee.github.io/2018/08/17/hyperledger-devtools-installing-error-log/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Hyperledger 개발 환경 구축하기</title>
      <link>https://j-s-lee.github.io/2018/08/11/getting-started-hyperledger-with-windows10-wsl/</link>
      <guid>https://j-s-lee.github.io/2018/08/11/getting-started-hyperledger-with-windows10-wsl/</guid>
      <pubDate>Sat, 11 Aug 2018 06:48:28 GMT</pubDate>
      <description>
      
        &lt;p&gt;윈도우 환경에서 &lt;code&gt;Hyperledger Composer&lt;/code&gt; 개발 환경 구축하는 과정을 정리하는 글&lt;/p&gt;
      
      </description>
      
      <content:encoded><![CDATA[<p>윈도우 환경에서 <code>Hyperledger Composer</code> 개발 환경 구축하는 과정을 정리하는 글</p><a id="more"></a><h3 id="Hyperledger-Composer-amp-Fabric-설치에-필요한-개발-툴"><a href="#Hyperledger-Composer-amp-Fabric-설치에-필요한-개발-툴" class="headerlink" title="Hyperledger Composer &amp; Fabric 설치에 필요한 개발 툴"></a>Hyperledger Composer &amp; Fabric 설치에 필요한 개발 툴</h3><ul><li>OS : Ubuntu Linux 14.04 / 16.04 LTS (both 64-bit), or Mac OS 10.12</li><li>Docker Engine : Version 17.03 or higher</li><li>Docker-Compose : Version 1.8 or higher</li><li>Node : 8.9 or higher (version 9 is not supported)</li><li>npm : v5.x</li><li>git : 2.9.x or higher</li><li>Python : 2.7.x</li><li>Editor : A code editor of user choice, recommend VSCode</li></ul><h3 id="1-개발-환경-설치"><a href="#1-개발-환경-설치" class="headerlink" title="1. 개발 환경 설치"></a>1. 개발 환경 설치</h3><h4 id="Windows-10-pro-설정"><a href="#Windows-10-pro-설정" class="headerlink" title="Windows 10 pro 설정"></a>Windows 10 pro 설정</h4><p><code>제어판</code> &gt; <code>프로그램</code> &gt; <code>프로그램 및 기능</code> &gt; <code>Windows 기능 켜기/끄기</code> &gt; <code>Hyper-V</code> 체크</p><ul><li style="list-style: none"><input type="checkbox" checked> Hyper-V</li></ul><ul><li><p>Windows GIT client &amp; shell <a href="https://gitforwindows.org" target="_blank" rel="noopener">설치</a></p></li><li><p>Node.js <a href="https://nodejs.org/ko/download/" target="_blank" rel="noopener">설치</a></p></li></ul><h4 id="prerequisites-다운로드"><a href="#prerequisites-다운로드" class="headerlink" title="prerequisites 다운로드"></a>prerequisites 다운로드</h4><p>위에 명시된 <code>hyperledger composer</code> 설치를 위해 필요한 시스템 패키지를 다운로드한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">curl -O https://hyperledger.github.io/composer/latest/prereqs-ubuntu.sh</span><br><span class="line">chmod u+x prereqs-ubuntu.sh</span><br><span class="line">./prereqs-ubuntu.sh</span><br></pre></td></tr></table></figure><p>패키지별 버전 확인을 통해 잘 설치되었는지 체크한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">nodejs -v <span class="comment"># node version check</span></span><br><span class="line"></span><br><span class="line">npm -v <span class="comment"># npm version check</span></span><br><span class="line"></span><br><span class="line">git --version <span class="comment"># git version check</span></span><br><span class="line"></span><br><span class="line">python --version <span class="comment"># python version check</span></span><br><span class="line"></span><br><span class="line">docker -v <span class="comment"># docker version check</span></span><br><span class="line"></span><br><span class="line">docker-compose -v <span class="comment"># docker-compose version check</span></span><br></pre></td></tr></table></figure><h3 id="3-컴포넌트-설치"><a href="#3-컴포넌트-설치" class="headerlink" title="3. 컴포넌트 설치"></a>3. 컴포넌트 설치</h3><p><code>composer-cli</code>는 필수 CLI 툴이고, 나머지는 개발 환경 구성에 꼭 필요한 부분은 아니다.</p><p>하지만 <a href="https://hyperledger.github.io/composer/latest/installing/development-tools.html" target="_blank" rel="noopener">공식 사이트</a>에서는 튜토리얼을 진행하거나 어플리케이션 개발을 할 때 유용하므로 함께 설치할 것을 권장하고 있다.</p><h4 id="CLI-툴-설치"><a href="#CLI-툴-설치" class="headerlink" title="CLI 툴 설치"></a>CLI 툴 설치</h4><ol><li><p>코어 CLI 툴</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g composer-cli@0.20</span><br></pre></td></tr></table></figure></li></ol><ol start="2"><li><p>RESTful API Server를 띄워주는 기능</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g composer-rest-server@0.20</span><br></pre></td></tr></table></figure></li></ol><ol start="3"><li><p>어플리케이션 assets 생성에 유용</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g generator-hyperledger-composer@0.20</span><br></pre></td></tr></table></figure></li></ol><ol start="4"><li><p><code>generator-hyperledger-composer</code> 같은 기능을 이용한 어플리케이션 생성을 위한 툴 Yeoman</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g yo</span><br></pre></td></tr></table></figure></li></ol><h4 id="Playground-설치"><a href="#Playground-설치" class="headerlink" title="Playground 설치"></a>Playground 설치</h4><ol><li><p>Playground - 간단한 수정, 테스팅을 브라우저 UI 환경에서 제공</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g composer-playground@0.20</span><br></pre></td></tr></table></figure></li></ol><h4 id="Hyperledger-Fabric-설치"><a href="#Hyperledger-Fabric-설치" class="headerlink" title="Hyperledger Fabric 설치"></a>Hyperledger Fabric 설치</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mkdir ~/fabric-dev-servers &amp;&amp; <span class="built_in">cd</span> ~/fabric-dev-servers</span><br><span class="line"></span><br><span class="line">curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz</span><br><span class="line">tar -xvf fabric-dev-servers.tar.gz</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/fabric-dev-servers</span><br><span class="line"><span class="built_in">export</span> FABRIC_VERSION=hlfv12</span><br><span class="line">./downloadFabric.sh</span><br></pre></td></tr></table></figure><h4 id="Hyperledger-Fabric-시작-종료"><a href="#Hyperledger-Fabric-시작-종료" class="headerlink" title="Hyperledger Fabric 시작/종료"></a>Hyperledger Fabric 시작/종료</h4><p>런타임을 처음 시작하는 경우 start 스크립트 실행 후 PeerAdmin card를 생성해야 한다.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/fabric-dev-servers</span><br><span class="line"><span class="built_in">export</span> FABRIC_VERSION=hlfv12</span><br><span class="line">./startFabric.sh</span><br><span class="line">./createPeerAdminCard.sh</span><br></pre></td></tr></table></figure><p>이후 런타임을 시작하거나 정지시킬 때는 <code>~/fabric-dev-servers/stopFabric.sh</code>, <code>~/fabric-dev-servers/startFabric.sh</code>을 이용하면 된다.</p><p>개발 세션을 종료할 경우엔 <code>~/fabric-dev-servers/stopFabric.sh</code> 실행 후에 <code>~/fabric-dev-servers/teardownFabric.sh</code>를 사용하면 된다. 만약 teardown 스크립트를 실행한다면, 다음에 런타임을 시작할 때 처음 런타임 시작과 같이 새로운 PeerAdmin card를 생성해줘야한다.</p><h4 id="Playground-실행"><a href="#Playground-실행" class="headerlink" title="Playground 실행"></a>Playground 실행</h4><p>playground web app을 실행하는 방법</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">composer-playground</span><br></pre></td></tr></table></figure><p>브라우저가 다음의 주소를 갖고 자동으로 열린다. <a href="http://localhost:8080/login" target="_blank" rel="noopener">http://localhost:8080/login</a></p><p>“My Business Networks” 화면에서  <code>createPeerAdminCard</code> 스크립트를 통해 생성한 <code>PeerAdmin@hlfv1</code> 카드가 보이지 않는다면 런타임이 정상적으로 시작되지 않은 것이다.</p><h3 id="참고자료"><a href="#참고자료" class="headerlink" title="참고자료"></a>참고자료</h3><ul><li><a href="https://d2fault.github.io/2018/04/30/20180430-setting-hyperledger-developement-environment/" target="_blank" rel="noopener">[Hyperledger] 개발 환경 구축하기(설치) | 잡동사니 수집광</a></li><li><a href="https://hyperledger.github.io/composer/latest/installing/installing-prereqs.html" target="_blank" rel="noopener">Installing pre-requisites | Hyperledger </a></li><li><a href="https://hyperledger.github.io/composer/latest/installing/development-tools.html" target="_blank" rel="noopener">Installing development-tools | Hyperledger</a></li></ul>]]></content:encoded>
      
      <comments>https://j-s-lee.github.io/2018/08/11/getting-started-hyperledger-with-windows10-wsl/#disqus_thread</comments>
    </item>
    
  </channel>
</rss>
