<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발 흔적</title>
    <link>https://wooong-dev.tistory.com/</link>
    <description>https://github.com/cothi  - 깃허브 
jiungdev@gmail.com - 이메일</description>
    <language>ko</language>
    <pubDate>Thu, 11 Jun 2026 13:44:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>coti-z</managingEditor>
    <image>
      <title>개발 흔적</title>
      <url>https://tistory1.daumcdn.net/tistory/4518885/attach/e7fcfd16d7e04548aee2d98d3dddbacd</url>
      <link>https://wooong-dev.tistory.com</link>
    </image>
    <item>
      <title>아이폰 (IOS) 앱 추천 - 2선</title>
      <link>https://wooong-dev.tistory.com/entry/ios-%EC%95%B1-2%EC%84%A0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.&amp;nbsp; nexto &amp;mdash; 오프라인에서도 완벽하게 동작하는 일정 관리 앱&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;calendar.png&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;2778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxfTI0/dJMcacCyXwK/PQ7uFxDkuOf42cAjeEhXIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxfTI0/dJMcacCyXwK/PQ7uFxDkuOf42cAjeEhXIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxfTI0/dJMcacCyXwK/PQ7uFxDkuOf42cAjeEhXIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxfTI0%2FdJMcacCyXwK%2FPQ7uFxDkuOf42cAjeEhXIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;322&quot; height=&quot;697&quot; data-filename=&quot;calendar.png&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;2778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1&amp;nbsp; 왜 만들었나&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비행기 안, 지하철, 데이터가 안 터지는 곳에서도 쓸 수 있는 제대로 된 일정 관리 앱이 없을까? 라는 단순한 궁금증에서 시작했다.&lt;br /&gt;서버 의존 없이, 오프라인 퍼스트로 동작하면서도 퀄리티를 타협하지 않는 앱을 목표로 개발을 시작했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;1.2&amp;nbsp; 주요 기능&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;캘린더&amp;nbsp;(이벤트,&amp;nbsp;반복&amp;nbsp;일정,&amp;nbsp;파일&amp;nbsp;첨부)&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;프로젝트&amp;nbsp;&amp;amp;&amp;nbsp;태스크&amp;nbsp;관리&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;포커스&amp;nbsp;타이머&amp;nbsp;(뽀모도로,&amp;nbsp;타이머,&amp;nbsp;스톱워치)&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;루틴&amp;nbsp;관리&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;데일리&amp;nbsp;체크인&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;알림&amp;nbsp;/&amp;nbsp;위젯&amp;nbsp;/&amp;nbsp;다크모드&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;한국어&amp;nbsp;&amp;middot;&amp;nbsp;영어&amp;nbsp;지원&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;1.3 현재 상황&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;처음엔&amp;nbsp;가볍게&amp;nbsp;시작했는데,&amp;nbsp;만들다&amp;nbsp;보니&amp;nbsp;점점&amp;nbsp;커졌다.&amp;nbsp;현재는&amp;nbsp;심화&amp;nbsp;기능&amp;nbsp;개발과&amp;nbsp;버그&amp;nbsp;수정을&amp;nbsp;병행하고&amp;nbsp;있고,&amp;nbsp;단순한&amp;nbsp;일정&amp;nbsp;관리를&amp;nbsp;넘어서&lt;br /&gt;&amp;nbsp;&amp;nbsp;프로젝트&amp;nbsp;&amp;middot;&amp;nbsp;습관&amp;nbsp;&amp;middot;&amp;nbsp;집중까지&amp;nbsp;한&amp;nbsp;곳에서&amp;nbsp;관리할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;방향으로&amp;nbsp;발전시키고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어: 영어, 한국어 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링크:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://apps.apple.com/us/app/gluon-todo-project-planner/id6758938759&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://apps.apple.com/us/app/gluon-todo-project-planner/id6758938759&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774614719389&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Gluon - Todo, Project Planner App - App Store&quot; data-og-description=&quot;Download Gluon - Todo, Project Planner by jiung han on the App Store. See screenshots, ratings and reviews, user tips, and more apps like Gluon - Todo, Project&amp;hellip;&quot; data-og-host=&quot;apps.apple.com&quot; data-og-source-url=&quot;https://apps.apple.com/us/app/gluon-todo-project-planner/id6758938759&quot; data-og-url=&quot;https://apps.apple.com/us/app/gluon-todo-project-planner/id6758938759&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nFCks/dJMb84p8vou/3VdbjBnkE4QheLyiYvxwk0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/7sMV4/dJMb9aKEWPp/Dvtiadiv6u9jkFb7aECj9K/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://apps.apple.com/us/app/gluon-todo-project-planner/id6758938759&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://apps.apple.com/us/app/gluon-todo-project-planner/id6758938759&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nFCks/dJMb84p8vou/3VdbjBnkE4QheLyiYvxwk0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/7sMV4/dJMb9aKEWPp/Dvtiadiv6u9jkFb7aECj9K/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Gluon - Todo, Project Planner App - App Store&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Download Gluon - Todo, Project Planner by jiung han on the App Store. See screenshots, ratings and reviews, user tips, and more apps like Gluon - Todo, Project&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;apps.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. SCANIO&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 개발 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scan이라는 앱은 좀 다양하게 있는데 이미 출시한 것도 많고 그런데 바코드, qr 을 생성하고 history 관리를 진행하며 좀 심화적인 것들도 가능하지 않을까? 라는 가벼운 생각에 개발을 진행하였습니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.2 기능&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;qr, barcode 인식이 가능하고 history 관리도 진행하고 있습니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.3 앞으로&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각에는 생각보다 오랜기간에 걸쳐서 심화된 기능을 개발할 것 같습니다. 고민이 많은 기능도 있고요 스캔이라는 것이 또 다양한 장르가 많아서요&amp;nbsp; 많은 기대 부탁드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출시: 영어권 국가, 한국(출시 예정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어: 영어, 한국어 (출시 예정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://apps.apple.com/us/app/scanio-qr-barcode/id6759646275&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://apps.apple.com/us/app/scanio-qr-barcode/id6759646275&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774614853382&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Scanio - QR &amp;amp; Barcode App - App Store&quot; data-og-description=&quot;Download Scanio - QR &amp;amp; Barcode by jiung han on the App Store. See screenshots, ratings and reviews, user tips, and more apps like Scanio - QR &amp;amp; Barcode.&quot; data-og-host=&quot;apps.apple.com&quot; data-og-source-url=&quot;https://apps.apple.com/us/app/scanio-qr-barcode/id6759646275&quot; data-og-url=&quot;https://apps.apple.com/us/app/scanio-qr-barcode/id6759646275&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ODzge/dJMb8QMbNwG/rrv8oGEc0PB2G6dMck8zJk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cimKwE/dJMb8U8TpOY/0ItZpHKwiXKKHA1vthNxPK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://apps.apple.com/us/app/scanio-qr-barcode/id6759646275&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://apps.apple.com/us/app/scanio-qr-barcode/id6759646275&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ODzge/dJMb8QMbNwG/rrv8oGEc0PB2G6dMck8zJk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cimKwE/dJMb8U8TpOY/0ItZpHKwiXKKHA1vthNxPK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Scanio - QR &amp;amp; Barcode App - App Store&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Download Scanio - QR &amp;amp; Barcode by jiung han on the App Store. See screenshots, ratings and reviews, user tips, and more apps like Scanio - QR &amp;amp; Barcode.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;apps.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 앱들도 있으나 안정권에 들어오면 리스트에 올려보도록 하겠습니다.&amp;nbsp; 읽어주셔서 감사합니다!&lt;/p&gt;</description>
      <category>etc/활동</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/76</guid>
      <comments>https://wooong-dev.tistory.com/entry/ios-%EC%95%B1-2%EC%84%A0#entry76comment</comments>
      <pubDate>Fri, 27 Mar 2026 21:44:51 +0900</pubDate>
    </item>
    <item>
      <title>유튜브 링크 복사 방법 총정리 (특정시간 포함)</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%9C%A0%ED%8A%9C%EB%B8%8C-%EB%A7%81%ED%81%AC-%EB%B3%B5%EC%82%AC-%EB%B0%A9%EB%B2%95-%EC%B4%9D%EC%A0%95%EB%A6%AC-%ED%8A%B9%EC%A0%95%EC%8B%9C%EA%B0%84-%ED%8F%AC%ED%95%A8</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;PC에서 링크 복사하기&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;방법 1: 공유 버튼 이용&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷_20260103_144431.png&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eQ2eEq/dJMcag5fOBE/kqAe5hF1sZ91mtucyjlA30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eQ2eEq/dJMcag5fOBE/kqAe5hF1sZ91mtucyjlA30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eQ2eEq/dJMcag5fOBE/kqAe5hF1sZ91mtucyjlA30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeQ2eEq%2FdJMcag5fOBE%2FkqAe5hF1sZ91mtucyjlA30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;538&quot; height=&quot;385&quot; data-filename=&quot;스크린샷_20260103_144431.png&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;유튜브 영상 재생 페이지 접속&lt;/li&gt;
&lt;li&gt;영상 하단의 &quot;공유&quot; 버튼 클릭&lt;/li&gt;
&lt;li&gt;&quot;복사&quot; 버튼 클릭&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;방법 2: 주소창 복사&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷_20260103_144951.png&quot; data-origin-width=&quot;1437&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nFDZL/dJMcabXaFtZ/pdjswChVe54WxoWHTmZa91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nFDZL/dJMcabXaFtZ/pdjswChVe54WxoWHTmZa91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nFDZL/dJMcabXaFtZ/pdjswChVe54WxoWHTmZa91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnFDZL%2FdJMcabXaFtZ%2FpdjswChVe54WxoWHTmZa91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;792&quot; height=&quot;374&quot; data-filename=&quot;스크린샷_20260103_144951.png&quot; data-origin-width=&quot;1437&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;브라우저 주소창 클릭&lt;/li&gt;
&lt;li&gt;Ctrl + C (또는 우클릭 &amp;gt; 복사)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;특정 시간대 링크 만들기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷_20260103_145909.png&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z2BAR/dJMcaiBWhaD/AwQql70HvFGC7FP9TyD1wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z2BAR/dJMcaiBWhaD/AwQql70HvFGC7FP9TyD1wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z2BAR/dJMcaiBWhaD/AwQql70HvFGC7FP9TyD1wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ2BAR%2FdJMcaiBWhaD%2FAwQql70HvFGC7FP9TyD1wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;425&quot; data-filename=&quot;스크린샷_20260103_145909.png&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;영상을 원하는 시간대로 이동하거나, 3번에서 시작시간 설정 후, 체크박스 선택&lt;/li&gt;
&lt;li&gt;&quot;공유&quot; 버튼 클릭&lt;/li&gt;
&lt;li&gt;&quot;시작 시간&quot; 체크박스 선택&lt;/li&gt;
&lt;li&gt;자동으로 시간이 설정됨&lt;/li&gt;
&lt;li&gt;복사 클릭&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가 팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;블로그에 유튜브 영상 넣기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷_20260103_151121-2.png&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caRVY4/dJMcaacSQxi/ojcdqnH7POFkPZDMf6IAn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caRVY4/dJMcaacSQxi/ojcdqnH7POFkPZDMf6IAn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caRVY4/dJMcaacSQxi/ojcdqnH7POFkPZDMf6IAn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaRVY4%2FdJMcaacSQxi%2FojcdqnH7POFkPZDMf6IAn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;453&quot; data-filename=&quot;스크린샷_20260103_151121-2.png&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 공유 버튼을 누르고 임베드를 누른다 그리고나서 아래의 사진처럼&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷_20260103_151300.png&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjX1Rn/dJMcafrJv4D/jPvKFXRtua0MVmEQTkXsFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjX1Rn/dJMcafrJv4D/jPvKFXRtua0MVmEQTkXsFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjX1Rn/dJMcafrJv4D/jPvKFXRtua0MVmEQTkXsFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjX1Rn%2FdJMcafrJv4D%2FjPvKFXRtua0MVmEQTkXsFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;333&quot; data-filename=&quot;스크린샷_20260103_151300.png&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 복사 버튼을 누르고&amp;nbsp; &amp;lt;iframe 을 복사하면 블로그에 넣어서 영상을 넣을 수 있다&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/UediEKOHI5E?si=N5SxIiE6doekTe_l&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유튜브 링크 복사는 생각보다 간단하죠? PC든 모바일이든 &quot;공유&quot; 버튼만 누르면 끝입니다. 특정 시간대 링크를 만들 때는 &quot;시작 시간&quot; 옵션도 가능하다는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 정리:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 공유: 공유 버튼 &amp;rarr; 복사&lt;/li&gt;
&lt;li&gt;특정 시간: 공유 버튼 &amp;rarr; 시작 시간 체크 &amp;rarr; 복사&lt;/li&gt;
&lt;li&gt;수동 시간 추가: URL 뒤에 ?t=초 추가&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>지식</category>
      <category>복사넣기</category>
      <category>유튜브 영상</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/74</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%9C%A0%ED%8A%9C%EB%B8%8C-%EB%A7%81%ED%81%AC-%EB%B3%B5%EC%82%AC-%EB%B0%A9%EB%B2%95-%EC%B4%9D%EC%A0%95%EB%A6%AC-%ED%8A%B9%EC%A0%95%EC%8B%9C%EA%B0%84-%ED%8F%AC%ED%95%A8#entry74comment</comments>
      <pubDate>Sat, 3 Jan 2026 15:15:02 +0900</pubDate>
    </item>
    <item>
      <title>유튜브 바로가기 링크</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%9C%A0%ED%8A%9C%EB%B8%8C-%EB%B0%94%EB%A1%9C%EA%B0%80%EA%B8%B0-%EB%A7%81%ED%81%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767366783034&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;- YouTube&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.youtube.com&quot; data-og-source-url=&quot;https://www.youtube.com/&quot; data-og-url=&quot;https://www.youtube.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d5iwST/hyZQSGKuKx/QX4yJcwzEhKIc8YFVwMo0k/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200&quot;&gt;&lt;a href=&quot;https://www.youtube.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.youtube.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d5iwST/hyZQSGKuKx/QX4yJcwzEhKIc8YFVwMo0k/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;- YouTube&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.youtube.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유튜브 바로가기 링크는 위의 링크로 접속하여 바로 갈 수 있다.&lt;/p&gt;</description>
      <category>지식</category>
      <category>바로가기</category>
      <category>유튜브</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/73</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%9C%A0%ED%8A%9C%EB%B8%8C-%EB%B0%94%EB%A1%9C%EA%B0%80%EA%B8%B0-%EB%A7%81%ED%81%AC#entry73comment</comments>
      <pubDate>Sat, 3 Jan 2026 00:13:38 +0900</pubDate>
    </item>
    <item>
      <title>유튜브 프리미엄 가격 정책 - 2026년 (라이트 포함)</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%9C%A0%ED%8A%9C%EB%B8%8C-%ED%94%84%EB%A6%AC%EB%AF%B8%EC%97%84-%EA%B0%80%EA%B2%A9-%EC%A0%95%EC%B1%85-2026%EB%85%84-%EB%9D%BC%EC%9D%B4%ED%8A%B8-%ED%8F%AC%ED%95%A8</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;2026년 1월 2일 기준&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;현재 가격은?&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 32px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 15px;&quot;&gt;
&lt;td style=&quot;width: 16.6666%; height: 15px;&quot;&gt;요금제&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%; height: 15px;&quot;&gt;안드로이드/웹&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%; height: 15px;&quot;&gt;IOS&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;인원&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 15px;&quot;&gt;1인당 비용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6666%; height: 17px;&quot;&gt;개인&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%; height: 17px;&quot;&gt;14,900원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%; height: 17px;&quot;&gt;19,500원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;1명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;14,900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;가족&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;22,900원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;22,900원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;최대 6명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;3,817원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;학생&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;7990원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;7990원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;1명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;7990원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;라이트(예정)&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;8500원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;10900원&lt;/td&gt;
&lt;td style=&quot;width: 16.6666%;&quot;&gt;1명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;8500원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;라이트 버전이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유튜브 프리미엄 라이트는 기존 프리미엄에서 유튜브 뮤직을 빼고 가격을 낮춘 버전이다. 유튜브 뮤직을 사용하지 않는다면 유튜브 프리미엄 라이트 버전을 기다리고 구매하는 것을 추천한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;IOS가 비싼 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IOS 앱에서 결제하면 애플 수수료 때문에 가격이 더 비싸니 웹에서 결제하는 것이 현명하다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>지식</category>
      <category>유튜브 프리미엄</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/72</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%9C%A0%ED%8A%9C%EB%B8%8C-%ED%94%84%EB%A6%AC%EB%AF%B8%EC%97%84-%EA%B0%80%EA%B2%A9-%EC%A0%95%EC%B1%85-2026%EB%85%84-%EB%9D%BC%EC%9D%B4%ED%8A%B8-%ED%8F%AC%ED%95%A8#entry72comment</comments>
      <pubDate>Fri, 2 Jan 2026 23:15:47 +0900</pubDate>
    </item>
    <item>
      <title>neovim(nvim) 설정 - 플러그인 (설정, 설치, 폴더 구조)</title>
      <link>https://wooong-dev.tistory.com/entry/Neovim-%EC%84%A4%EC%A0%95-%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8-%EC%84%A4%EC%A0%95-%EC%84%A4%EC%B9%98-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2024 - 07 - 07 일에 포스팅한 자료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 저는 GUI IDE인 VSCODE 사용하여 개발을 진행하지만, 작은 프로젝트나 설정 파일을 건드려야 할 때 주로 Neovim을 사용하고는 하는데요&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NEOVIM 처음 입문할 때, 폴더 구조나 플러그인을 사용할 때, 감이 안잡히는 경우가 있어 공유하고자 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 소개&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[1.1] Neovim 이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Neovim&lt;/code&gt;은 Vim을 새롭게 개발한 것이 아닌 Vim에 확장 형태로 개발되어 NVIM 내부에서 설정이나 플러그인을 다루는 등, &lt;code&gt;vimscript&lt;/code&gt;로 작성하여 사용 가능하고, 추가적으로 &lt;code&gt;lua&lt;/code&gt;도 사용이 가능합니다. neovim의 비전에 따르면 VIM의 좋은 부분은 그대로 가져오고 그 이상을 원하는 사용자를 위해서 만들어졌다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가된 기능 중에는 하나는 기본적으로 코드 자동 완성, 정의로 이동 등을 지원하는 &lt;code&gt;LSP(Language Server Protocol&lt;/code&gt;를 지원하기에 nvim-lspconfig 플러그인을 통해서 쉽게 사용이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NVIM에 대하여, 자세하게 알고 싶으면 많은 정보는 아래의 링크에 들어가 확인할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로드맵: &lt;a href=&quot;https://neovim.io/roadmap/&quot;&gt;https://neovim.io/roadmap/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;NVIM: &lt;a href=&quot;https://neovim.io/charter/&quot;&gt;https://neovim.io/charter/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1720364928423&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Roadmap - Neovim&quot; data-og-description=&quot;Roadmap This roadmap gives an overview of the project direction. A detailed list of features planned or under consideration can be found in the project boards; priorities are tracked by milestones: Version numbers (0.1, 0.2, 0.2.1, &amp;hellip;) track production re&quot; data-og-host=&quot;neovim.io&quot; data-og-source-url=&quot;https://neovim.io/roadmap/&quot; data-og-url=&quot;https://neovim.io/roadmap/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://neovim.io/roadmap/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://neovim.io/roadmap/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Roadmap - Neovim&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Roadmap This roadmap gives an overview of the project direction. A detailed list of features planned or under consideration can be found in the project boards; priorities are tracked by milestones: Version numbers (0.1, 0.2, 0.2.1, &amp;hellip;) track production re&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;neovim.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Neovim 폴더 구조&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.1] NVIM 설정 (ROOT 폴더)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon.png&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byaMfg/btsIqSEV5KP/moYddio587kdReKkKLFbL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byaMfg/btsIqSEV5KP/moYddio587kdReKkKLFbL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byaMfg/btsIqSEV5KP/moYddio587kdReKkKLFbL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyaMfg%2FbtsIqSEV5KP%2FmoYddio587kdReKkKLFbL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1492&quot; height=&quot;564&quot; data-filename=&quot;carbon.png&quot; data-origin-width=&quot;1492&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치를 진행할 때, 설정 파일은 직접 만들어지지 않습니다. NVIM 문서에 따르면 사용하는 플랫폼에 따라서 유닉스, 리눅스, Windows는 위의 그림에 보여진 경로를 확인하여 해당 경로에 파일을 만들어 설정하면 설정을 시작할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유닉스, 리눅스: ~/.config/nvim/init.vim (or init.lua)&lt;/li&gt;
&lt;li&gt;윈도우: ~/AppData/Local/nvim/init.vim (or init.lua)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정 폴더가 없는 경우 만들어서 직접 만들어서 해결하도록 설계되어 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; nvim 폴더의 경로를 지정하고 싶다면 환경변수인 &lt;code&gt;XDG_CONFIG_HOME&lt;/code&gt;을 지정하며 루트 폴더를 수정하면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.2] nvim 설정파일, 내부 폴더 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따로 명확한 설정 폴더의 아키택처 구조는 없고, nvim은 유연성을 제공하기에, 사용자가 편한 생산성있고 가독성 있는 관리하기 편한 폴더 구조를 선택하여 만들어 사용하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단, 유저가 &lt;code&gt;init.lua&lt;/code&gt; 또는 &lt;code&gt;init.vim&lt;/code&gt;을 지정된 경로(위의 설명 참고) 에 만들어 거기서 tree 구조로 만들어 사용해야하는 구조&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 각각 플램폼에 따라 다른 위에서 설명한 경로에&amp;nbsp; 설정 파일(init.lua) 을 만들면,&amp;nbsp; NVIM의 실행파일이 설정 파일(init.lua)을 인식하여 설정한 내용(keymap, options) 사용할 수 있기에 만들어져 있지 않다면, 위의 설명에서 설명한 경로를 따라가 만들도록 합시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제, 만들어진 설정 파일(init.lua) 에는 keymap, plugin, theme 등 다양한 설정을 넣어서 생산성을 극대화할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제 폴더 구조를 잡아볼까요?&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.3] 실제 적용&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1) 전체적인 구조&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 실제로 사용하고 있는 폴더 구조로 예시를 들겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (1).png&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;1220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NMZu9/btsIptfmWnp/XSJxkCDnIF7o2krRUtp9Ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NMZu9/btsIptfmWnp/XSJxkCDnIF7o2krRUtp9Ek/img.png&quot; data-alt=&quot;폴더 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NMZu9/btsIptfmWnp/XSJxkCDnIF7o2krRUtp9Ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNMZu9%2FbtsIptfmWnp%2FXSJxkCDnIF7o2krRUtp9Ek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1364&quot; height=&quot;1220&quot; data-filename=&quot;carbon (1).png&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;1220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;폴더 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;처음부터 너무 복잡하게 사용할 필요는 없습니다. 하지만 관리를 편하게 하기 위해서, 폴더 구조를 잡고 하나하나 추가하면서 사용하는 방법을 추천&lt;/b&gt;하도록 하겠습니다. 필요 없고 간단하게 사용하고 싶다면 만들지 않으면 됩니다. 이를 얘기하는 이유는 시간을 많이 잡을 수 있고, 나중에 구조가 안잡혀 있다면 그 또한 리팩토링하느라 시간이 많이 잡히기에 선택을 잘할 필요는 있습니다 따라서, 대략 구조만 잡는다 생각하면 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 플러그인 사용하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인을 사용할 수 있는 방법은 여러가지입니다. 저는 요즘 nvim 플러그인을 설치하는데 인기 있는 lazy.nvim을 사용하도록 하겠습니다. lazy.nvim root 폴더에 &lt;code&gt;init.lua&lt;/code&gt;에서 처음 시작할 때, plugin을 먼저 설치하는 방식을 택해서 사용합니다. 아래와 같이요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설정 참고:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://lazy.folke.io/installation&quot;&gt;https://lazy.folke.io/installation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1720364933284&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot; ️ Installation | lazy.nvim&quot; data-og-description=&quot;There are multiple ways to install lazy.nvim.&quot; data-og-host=&quot;lazy.folke.io&quot; data-og-source-url=&quot;https://lazy.folke.io/installation&quot; data-og-url=&quot;https://lazy.folke.io/installation&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/F51XS/hyWvP8XF8m/9Pt5EkXMzFMow0oZCxpSsk/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/g9hFG/hyWzxS7lIY/fV7rqkYW1ru1xFqzpOgMVk/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://lazy.folke.io/installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lazy.folke.io/installation&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/F51XS/hyWvP8XF8m/9Pt5EkXMzFMow0oZCxpSsk/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/g9hFG/hyWzxS7lIY/fV7rqkYW1ru1xFqzpOgMVk/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt; ️ Installation | lazy.nvim&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;There are multiple ways to install lazy.nvim.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lazy.folke.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (4).png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FrkJO/btsIq9Grwhq/BOv0Qd5oSvqrTDgqamkE51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FrkJO/btsIq9Grwhq/BOv0Qd5oSvqrTDgqamkE51/img.png&quot; data-alt=&quot;nvim/init.lua 파일 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FrkJO/btsIq9Grwhq/BOv0Qd5oSvqrTDgqamkE51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFrkJO%2FbtsIq9Grwhq%2FBOv0Qd5oSvqrTDgqamkE51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;1620&quot; data-filename=&quot;carbon (4).png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1620&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nvim/init.lua 파일 내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1) 코드 설명&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;4 ~ 18 라인 (local ~ lazypath)&lt;/b&gt;&lt;br /&gt;&lt;code&gt;부트스트랩(4~17)&lt;/code&gt;에서는 lazy.nvim인 플러그인 매니저가 존재하는지 확인하는 과정입니다. 플러그인 매니저가 존재하지 않는다면,&amp;nbsp; git 명령을 이용해서 clone하여 받아오는 과정입니다. 저장되는 곳은 플랫폼에 따라 다릅니다. 아래 리스트를 참고하여 주세요&amp;nbsp;&lt;/li&gt;
&lt;li&gt;linux : ~/.local/share/nvim/lazy/lazy.nvim&lt;/li&gt;
&lt;li&gt;window : % LOCALAPPDATA%\nvim-data\lazy\lazy.nvim&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;22번 라인 (require ~ plugins)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 플러그인 매니저가 정상적으로 사용이 가능하니, require(&quot;lazy&quot;). setup(&quot;plugins&quot;)의 22번 라인에서 플러그인 설정을 로드하게 되는 과정입니다. 22번 라인에서 init.lua라는 문구를 호출한다 명시하지 않았습니다. 이는 Lua 표준 동작을 따라는 &lt;code&gt;Neovim의 runtimepath 검색 메커니즘&lt;/code&gt;에 따라서 행동하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (5).png&quot; data-origin-width=&quot;1798&quot; data-origin-height=&quot;840&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZL7GD/btsIqDBgCvF/GiH5fZqk1nllzZiRnHXab0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZL7GD/btsIqDBgCvF/GiH5fZqk1nllzZiRnHXab0/img.png&quot; data-alt=&quot;nvim 문서&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZL7GD/btsIqDBgCvF/GiH5fZqk1nllzZiRnHXab0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZL7GD%2FbtsIqDBgCvF%2FGiH5fZqk1nllzZiRnHXab0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1798&quot; height=&quot;840&quot; data-filename=&quot;carbon (5).png&quot; data-origin-width=&quot;1798&quot; data-origin-height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nvim 문서&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림에 nvim 문서에는 requre('mod')를 찾을 때, 먼저 mod.lua -&amp;gt; init.lua를 찾는 것을 확인할 수 있습니다. 파일 검색 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;메커니즘이 확인되었으니, 이제 plugins.lua라는 파일이 있는지 확인 후에는 plugins/init.lua를 찾게 되는 것을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;25~26 라인 (keymap, options)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 라인은 플러그인과 상관(?) 없으나 의미는 위와 같습니다. lua 검색 메커니즘에 따라서 config라는 폴더를 찾고 options를 찾게 되는 겁니다. 해당 파일 안에는 단축키, 옵션이 들어가지만 해당 설명까지 하면 블로그 포스트가 길어질 것 같아, 다음 글에 작성하도록 하겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2) 플러그인 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;22번 라인&lt;/code&gt;으로 돌아가, 이제 &lt;b&gt;pluginst/init.lua&lt;/b&gt; 에서 해야 할 일을 지정해 줍니다. 아래와 같이 플러그인을 설치해 주면 되는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (8).png&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;1520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p0rwQ/btsIqdQlW2U/90MOZ9lOdcU6K90qEHZe6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p0rwQ/btsIqdQlW2U/90MOZ9lOdcU6K90qEHZe6K/img.png&quot; data-alt=&quot;lazy.nvim&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p0rwQ/btsIqdQlW2U/90MOZ9lOdcU6K90qEHZe6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp0rwQ%2FbtsIqdQlW2U%2F90MOZ9lOdcU6K90qEHZe6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1396&quot; height=&quot;1520&quot; data-filename=&quot;carbon (8).png&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;1520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;lazy.nvim&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 &lt;code&gt;return&lt;/code&gt; 구조를 선택했냐면 아래의 링크인 lazy.nvim 문서를 참고하여 만들었기에 따로 설명을 하지는 않겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;lazy.vim의&amp;nbsp;구조:&amp;nbsp;&lt;a href=&quot;https://lazy.folke.io/usage/structuring&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://lazy.folke.io/usage/structuring&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1720364946057&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;  Structuring Your Plugins | lazy.nvim&quot; data-og-description=&quot;Some users may want to split their plugin specs in multiple files.&quot; data-og-host=&quot;lazy.folke.io&quot; data-og-source-url=&quot;https://lazy.folke.io/usage/structuring&quot; data-og-url=&quot;https://lazy.folke.io/usage/structuring&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b1hv0D/hyWvQfI2ul/ZkjgEeSL88KKy8CSVqm9DK/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/cdEeQj/hyWzEdDpDT/R6Im3BlY0ZUzwDl1h3PTT0/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://lazy.folke.io/usage/structuring&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lazy.folke.io/usage/structuring&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b1hv0D/hyWvQfI2ul/ZkjgEeSL88KKy8CSVqm9DK/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/cdEeQj/hyWzEdDpDT/R6Im3BlY0ZUzwDl1h3PTT0/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;  Structuring Your Plugins | lazy.nvim&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Some users may want to split their plugin specs in multiple files.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lazy.folke.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 추천이기에 더 좋은 구조가 있다면 공유하거나 사용하면 될 것 같습니다. 하지만, 저는 문서의 추천을 따르는 편이기에 그렇게 설정하도록 하겠습니다. 이외에 각각의 플러그인 설치 방법은 각각의 보통 유명한 nvim 플러그인이라면 README에 친절하게 설명이 돼있을 것입니다. 아마 모든 플러그인이 표준을 맞추기에 위의 그림처럼 설치를 한다면 사용이 가능할 것 입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;25 라인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5 ~ 20번 라인은 이해가 갈 것 입니다. 배열 구조로 각각의 플러그인이 명시되어 설치되고 있지만, 특이한 방식으로 작성이 된 것으로 확인이 됩니다. 이는 plugins 폴더에 있는 telescope.lua 파일을 따로 만들어서 지정하여 설치하고 telescope 플러그인을 설정하려고 하는 의도입니다. 주로 이렇게 import 방식을 하는 이유는 상대적으로 다른 플러그인 보다 telescope 설정이 길어져서 따로 파일을 두어 관리를 진행하겠다는 의도입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;plugins/telescope.lua&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (10).png&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;1648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/69SPA/btsIrxG3G5M/0lR9kRYmp5gLIOEf51uPu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/69SPA/btsIrxG3G5M/0lR9kRYmp5gLIOEf51uPu0/img.png&quot; data-alt=&quot;telescope&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/69SPA/btsIrxG3G5M/0lR9kRYmp5gLIOEf51uPu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F69SPA%2FbtsIrxG3G5M%2F0lR9kRYmp5gLIOEf51uPu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1836&quot; height=&quot;1648&quot; data-filename=&quot;carbon (10).png&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;1648&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;telescope&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;telescope.lua&lt;/code&gt; 파일에는 이렇게 설정이 되어 있습니다. &lt;code&gt;plugins/init.lua&lt;/code&gt; 파일에 있는 다른 설정과 비슷한 구조를 가지고 있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 플러그인 소개&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[4.1] 다양한 플러그인 들을 소개&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rockerBOO/awesome-neovim&quot;&gt;https://github.com/rockerBOO/awesome-neovim&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[4.1] 플러그인을 조합할 시간이 없을 때&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/AstroNvim/AstroNvim&quot;&gt;https://github.com/AstroNvim/AstroNvim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/NvChad/NvChad&quot;&gt;https://github.com/NvChad/NvChad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/NvChad/NvChad&quot;&gt;https://github.com/NvChad/NvChad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 플러그인을 사용할 때, 주의할 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인을 사용할 때, 꼭 미리 설치해야하는 것(REQUIREMENTS 등) 들은 README에 적혀있습니다. 따라서, 플러그인이 사용이 안된다면 이러한 점들을 유의하여 살펴볼 필요가 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 설명한 구조로 플러그인을 사용할 수 있으며, 위의 설명에 포함하지 않는 폴더 구조에 있는 파일에 대해서는 다음 편에&amp;nbsp;블로그에 올리도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;</description>
      <category>etc/VIM, NVIM 에디터</category>
      <category>nvim</category>
      <category>Vim</category>
      <category>기본</category>
      <category>사용법</category>
      <category>추천</category>
      <category>플러그인</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/70</guid>
      <comments>https://wooong-dev.tistory.com/entry/Neovim-%EC%84%A4%EC%A0%95-%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8-%EC%84%A4%EC%A0%95-%EC%84%A4%EC%B9%98-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0#entry70comment</comments>
      <pubDate>Sun, 7 Jul 2024 23:39:51 +0900</pubDate>
    </item>
    <item>
      <title>동시성 테스트 - read econnreset 오류 (feat. nestjs, sql)</title>
      <link>https://wooong-dev.tistory.com/entry/%EB%8F%99%EC%8B%9C%EC%84%B1-%ED%85%8C%EC%8A%A4%ED%8A%B8-read-econnresetfeat-nestjs-sql</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;NESTJS에서&amp;nbsp; 동시성 테스트를 하던 도중, read econnreset 이 발생했다.&amp;nbsp; 해결하려 많은 시간을 소비하여 이런 케이스를 가진 분들이 빠르게 해결했으면 좋겠어서, &lt;b&gt;해당 오류에 대한 해결법과 앞으로 이런 오류가 발생하고 해결한 뒤, 한 번쯤 생각해봐야 할 공부 리스트를 공유하려고 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;0. 코드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB: Postgresql, Typeorm&lt;/li&gt;
&lt;li&gt;backend: nestjs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw6Xbs/btsIhixyGYO/UfwtlqP1kINDx87PuoI0JK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw6Xbs/btsIhixyGYO/UfwtlqP1kINDx87PuoI0JK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw6Xbs/btsIhixyGYO/UfwtlqP1kINDx87PuoI0JK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw6Xbs%2FbtsIhixyGYO%2FUfwtlqP1kINDx87PuoI0JK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;579&quot; data-filename=&quot;carbon.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 문제점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 작성하고 동시성 테스트를 진행하였다. 간단하게 설명하자면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;특강 API로 선착순으로 100명을 받는다&lt;/li&gt;
&lt;li&gt;따라서, 각기 다른 유저, 이메일로 총 100개의 Request로 만들고 들어온 순서에 맞게 처리해야 한다. 뒤에 들어온 5개의 요청은 100개로 한정해서 선착순으로 받기 때문에 5개는 실패 반환 처리를 해야 합니다.&lt;/li&gt;
&lt;li&gt;그런데 여기서, &lt;b&gt;30~40개의 요청만 성공 요청이 되고, 뒤에 요청은 처리가 되지 않는 현상이 발생하게 됩니다.&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;read econnreset 오류 발생&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;해당 오류에 대해서 검색해 봐도 정확히 판단(서버?, DB?, 운영체제?) 하기는 어려웠습니다&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 해결법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저의 해결법은 이러했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 만약 TypeORM을 사용하고 있다면 설정값에서 connectTimeoutMS라는 값을 넣어 옵션을 넣어 원하는 TimeoutMS의 값을 수정하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. TypeORM을 사용하고 있지않고, 다른 방법을 찾아야 한다면 해당 DB에 ConnectionTime 설정을 찾아봐야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (2).png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckXdt6/btsIgCQ4lDt/OKVTMg8KDzQuwQPBFGjT91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckXdt6/btsIgCQ4lDt/OKVTMg8KDzQuwQPBFGjT91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckXdt6/btsIgCQ4lDt/OKVTMg8KDzQuwQPBFGjT91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckXdt6%2FbtsIgCQ4lDt%2FOKVTMg8KDzQuwQPBFGjT91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;788&quot; height=&quot;481&quot; data-filename=&quot;carbon (2).png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 설정 변경으로, 수정을 하고 connectTimeoutMS 부분을 넉넉하게 늘려줍니다. 그리고 나서 다시 e2e 테스트를 수행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;carbon (2).png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lFFlR/btsIhPn7XK1/urw0xGRHkO5UJMX6Y8lko1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lFFlR/btsIhPn7XK1/urw0xGRHkO5UJMX6Y8lko1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lFFlR/btsIhPn7XK1/urw0xGRHkO5UJMX6Y8lko1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlFFlR%2FbtsIhPn7XK1%2Furw0xGRHkO5UJMX6Y8lko1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;784&quot; height=&quot;218&quot; data-filename=&quot;carbon (2).png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100개의 요청이 20820ms로 많은 시간이 걸린 뒤에 해결되게 됩니다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 무슨 문제?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 마다 connectionTimout 기본값이 설정되어 있어 많은 요청에 있어 뒤에 있는 요청들이 timeout 문제가 발생된 문제점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 DB에서는 기본적으로 설정해 놓은 timeout 시간으로 인해서, 요청 대기열에서 비교적 빠르게 들어온 요청들은 정해진 시간 안에 처리가 되고 나머지는 앞에 요청을 처리하는 데 걸린 시간에 의해서 &lt;b&gt;대기열 뒤에 있는 요청에 대한 응답들은 Timeout 시켜서 뒤에 있던 해당 요청에 대한 응답이 없어 timeout이 발생하게 된 것입니다&lt;/b&gt;. 변경 결과, timeout 길이를 늘인 결과 맨 마지막 요청은 20820ms가 걸리고 나서야 요청을 받게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 앞으로&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이게 과연 근본적으로 해결법일까요? 일단 시간이 오래 걸린 다는 것은 확인하게 되었습니다. 그리고 컴퓨팅 파워 문제도 아니었습니다. 그런데 생각해 보면 마지막 요청들에 대한 응답이 오래 걸리면&amp;nbsp; 문제가 있습니다.&amp;nbsp; 따라서 전체에 총량 시간도 중요하지만 각 요청마다 빠르게 응답하기 위해서는 오류는 해결했으니 앞으로 아래와 같은 방법들이 필요할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 해야 할 일&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산처리&lt;/li&gt;
&lt;li&gt;DB를 처리하는 부분을 로직을 최적화&lt;/li&gt;
&lt;li&gt;DB 락 부분을 많이 고려하여 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;----&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 위와 같은 방법으로 해결이 안된다면 node 버전을 18로 변경해보자&lt;/p&gt;</description>
      <category>서버/오류 해결</category>
      <category>econnreset</category>
      <category>nestJS</category>
      <category>read econnreset</category>
      <category>비관적락</category>
      <category>오류</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/69</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EB%8F%99%EC%8B%9C%EC%84%B1-%ED%85%8C%EC%8A%A4%ED%8A%B8-read-econnresetfeat-nestjs-sql#entry69comment</comments>
      <pubDate>Sat, 29 Jun 2024 21:52:58 +0900</pubDate>
    </item>
    <item>
      <title>스택 이론 - C++ (백준 9012 문제풀이)</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%8A%A4%ED%83%9D-%EC%9D%B4%EB%A1%A0-C-%EB%B0%B1%EC%A4%80-9012-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1] 스택이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Drawing 2024-06-07 20.33.57.excalidraw.png&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ej6O0L/btsHTe2dyjd/LCPt4EogOcvCqxpJauzs7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ej6O0L/btsHTe2dyjd/LCPt4EogOcvCqxpJauzs7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ej6O0L/btsHTe2dyjd/LCPt4EogOcvCqxpJauzs7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fej6O0L%2FbtsHTe2dyjd%2FLCPt4EogOcvCqxpJauzs7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;993&quot; height=&quot;594&quot; data-filename=&quot;Drawing 2024-06-07 20.33.57.excalidraw.png&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;스택&lt;/code&gt;은 쌓는다라는 의미로 먼저 들어온 데이터가 마지막에 제일 나중에 들어온 데이터가 처음으로 꺼낼 수 있는 구조를 말합니다. 이를 LIFO(Last In First Out) 구조라고 합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f4f4f6; color: #9999a1; text-align: left;&quot;&gt;✏️ Note&lt;/span&gt; &lt;br /&gt;스택을 삽입하는 연산을 PUSH, 스택에 있는 데이터를 꺼내는 행위를 POP이라고 부릅니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[2] 스택의 ADT(Abstract Data Type)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ADT&lt;/code&gt;는 구현하는 구조(Stack)에 대해서 &lt;b&gt;구현 방법을 명시하지 않고&lt;/b&gt; 어떠한 데이터의 구조와 연산들을 하는지에 대한 설명(명세)을 말합니다. 스택의 연산에는 &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;isFull&lt;/code&gt;, &lt;code&gt;isEmpty&lt;/code&gt;, &lt;code&gt;top과&lt;/code&gt; 같은 연산들이 존재합니다. 아래의 설명을 보도록 하겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;push()&lt;br /&gt;&lt;code&gt;push&lt;/code&gt;는 스택에 데이터를 넣는 연산을 수행합니다.&lt;/li&gt;
&lt;li&gt;pop()&lt;br /&gt;&lt;code&gt;pop&lt;/code&gt;은 가장 최근에 스택에 &lt;code&gt;push 한&lt;/code&gt; 데이터를 꺼내어, 데이터를 반환합니다.&lt;/li&gt;
&lt;li&gt;isFull()&lt;br /&gt;&lt;code&gt;isFull&lt;/code&gt;은 스택에 데이터가 더 들어갈 공간이 있는지 확인합니다. 공간이 없다면 &lt;code&gt;True&lt;/code&gt;를 반환 있다면 &lt;code&gt;False&lt;/code&gt;를 반환합니다.&lt;/li&gt;
&lt;li&gt;isEmpty()&lt;br /&gt;&lt;code&gt;isEmpty&lt;/code&gt;는 스택의 공간에 데이터가 하나 이상이라도 있는지를 확인하는 것이며, 있다면 &lt;code&gt;False&lt;/code&gt;, 없다면 &lt;code&gt;True&lt;/code&gt;를 반환합니다.&lt;/li&gt;
&lt;li&gt;top()&lt;br /&gt;&lt;code&gt;top&lt;/code&gt;은 가장 최근에 &lt;code&gt;push 한&lt;/code&gt; 데이터를 확인합니다.&lt;/li&gt;
&lt;li&gt;size()&lt;br /&gt;&lt;code&gt;size&lt;/code&gt;는 스택의 최대 크기를 확인할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[3] 스택 사용해 보기 - C++&lt;/h2&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stack&amp;gt;

using namespace std;
int main() {
    stack&amp;lt;int&amp;gt; st;
    // push  연산
    st.push(1);
    st.push(2);
    st.push(3);


    // 스택이 isEmpty에 대해서 True를 반환할 때까지 pop 수행

    while(!st.empty()) {
        cout &amp;lt;&amp;lt; st.top() &amp;lt;&amp;lt; &quot; &quot;; // 가장 최근에 넣은 데이터 출력
        st.pop(); // // 데이터를 pop 수행
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[4] 괄호 짝 맞추기 문제&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원본 링크&lt;br /&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9012&quot;&gt;https://www.acmicpc.net/problem/9012&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;(1) 설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;괄호 문자열은 두 개의 괄호 기호인 &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt; 만으로 구성되어 있는 문자열입니다. &lt;code&gt;(&lt;/code&gt; 문자열을 스택에 넣어두고, &lt;code&gt;) 문자열이&lt;/code&gt; 있을 때에 스택에 &lt;code&gt;(&lt;/code&gt;가 있는지 확인 후 없다면 NO를 출력하거나 있다면 &lt;code&gt;(&lt;/code&gt;을 pop을 수행하고 다음 문자열을 검사합니다. N의 길이만큼 스택을 이용해서 시간제한은 점근 표기법 O(n)에 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;(2) 코드&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stack&amp;gt;

using namespace std;



bool solution (string brakets) {
    stack&amp;lt;char&amp;gt; st;

    for (int i = 0; i &amp;lt; brakets.length(); i++) {
        if (brakets[i] == '(') {
            st.push('(');
        } else {
            if (st.empty()) return false;
            st.pop();
        }
    }
    // 스택이 비어있다면 모든 괄호가 닫힌 것으로 확인한다.
    if (st.empty()) return true;
    // 스택이 비어있지 않다면 모든 괄호가 닫히지 않은 것으로 확인한다
    return false;
}

int main() {
    int n;
    cin &amp;gt;&amp;gt; n;

    string brakets;
    for (int i = 0; i &amp;lt; n; i++) {
        cin &amp;gt;&amp;gt; brakets;
        bool isBraket = solution(brakets);
        if (isBraket) cout &amp;lt;&amp;lt; &quot;YES&quot; &amp;lt;&amp;lt; endl;
        else cout &amp;lt;&amp;lt; &quot;NO&quot; &amp;lt;&amp;lt; endl;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #292a2d; color: #9999a1; text-align: left;&quot;&gt;&lt;/span&gt; &lt;span style=&quot;background-color: #f4f4f6; color: #9999a1; text-align: left;&quot;&gt;✏️ Note&lt;/span&gt; &lt;br /&gt;stack의 push와 pop은 시간복잡도가 O(1)입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;%5B4%5D%20%EC%B0%B8%EA%B3%A0%EB%AC%B8%ED%97%8C-1&quot; style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;#%5B4%5D%20%EC%B0%B8%EA%B3%A0%EB%AC%B8%ED%97%8C-1&quot;&gt;[4] 참고문헌&lt;/a&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;박경록, 코딩 테스트 합격자 되기 C++편&lt;/li&gt;
&lt;li&gt;박경록 저자님의 스터디에 참가하여 정리하며 작성한 글입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/이론</category>
      <category>문제</category>
      <category>스택</category>
      <category>알고리즘</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/68</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%8A%A4%ED%83%9D-%EC%9D%B4%EB%A1%A0-C-%EB%B0%B1%EC%A4%80-9012-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4#entry68comment</comments>
      <pubDate>Sat, 8 Jun 2024 06:10:57 +0900</pubDate>
    </item>
    <item>
      <title>배열 - C++ ( 문제 포함 )</title>
      <link>https://wooong-dev.tistory.com/entry/%EB%B0%B0%EC%97%B4-C-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EB%AC%B8%EC%A0%9C-%ED%8F%AC%ED%95%A8</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[1] 배열 개념&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;357&quot; data-origin-height=&quot;157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mwLvS/btsHHm2fL90/qOfHuNEkWbPIsKesmwoKk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mwLvS/btsHHm2fL90/qOfHuNEkWbPIsKesmwoKk0/img.png&quot; data-alt=&quot;배열&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mwLvS/btsHHm2fL90/qOfHuNEkWbPIsKesmwoKk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmwLvS%2FbtsHHm2fL90%2FqOfHuNEkWbPIsKesmwoKk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;357&quot; height=&quot;157&quot; data-origin-width=&quot;357&quot; data-origin-height=&quot;157&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배열&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열은 순서대로 원소들이 연속적인 형태로 구성되어 있는 구조이며, 여러 타입으로 지정되어 효율적으로 관리를 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[1-1] 배열 선언&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열의 경우, 정수형 변수를 여러 개 선언해서 관리하기보다는 정수형 배열을 선언해서 관리하는 게 더욱 효율적입니다. 비교하는 예시를 아래와 같은 예시로 보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;// ...
int main() {

    // 인트형 변수 5개 선언
    int a1 = 1;
    int a2 = 2;
    int a3 = 3;
    int a4 = 4;
    int a5 = 5;
    cout &amp;lt;&amp;lt; a1 &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; a2 &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; a3 &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; a4 &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; a5 &amp;lt;&amp;lt; endl;

    // 1차원 배열 선언, for 문을 이용해 간편하게 출력
    int arr[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i &amp;lt; 5; i++) {
        cout &amp;lt;&amp;lt; arr[i] &amp;lt;&amp;lt; endl;
    }

    // 2차원 배열 선언
    int arr2[3][3] = {{1,2,3},{1,2,3},{1,2,3}}
    for (int i = 0; i &amp;lt; 3; i++) {
        for (int j = 0; i &amp;lt; 3; j++) {
            cout &amp;lt;&amp;lt; arr2[i][j];
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[1-2] 배열과 차원&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열은 2차원 배열과 그 이상의 다차원 배열을 이용하기도 하지만 컴퓨터 메모리 구조는 1차원으로 이루어져 있기에 다차원 배열은 컴퓨터 메모리의 1차원 공간에 연속 할당되어 나타나게 됩니다. 아래의 코드 예시를 보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;(1) 배열의 접근 및 제어&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;변수명 앞에 &amp;amp;를 붙이면 변수와 배열의 주소값을 하도록 하겠습니다. 아래의 예시의 출력 결과에 따라서, 배열을 저장하는 메모리 구조가 연속적이라고 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;// ...
int main() {
    // 배열 선언
    int arr[3] = {100, 200, 300};
    for (int i = 0; i &amp;lt; 3; i++) {
        cout &amp;lt;&amp;lt; &amp;amp;arr[i] &amp;lt;&amp;lt; endl;
    }
}

/*
    출력결과
    C++ test.cpp &amp;amp;&amp;amp; ./a.out
    0x7ffcbd97515c
    0x7ffcbd975160
    0x7ffcbd975164
*/&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;  NOTE&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;- int의 크기는 4바이트 이므로 주소가 4 증가&lt;br /&gt;- double은 8 바이트라서 주소가 8 증가&lt;br /&gt;- char 는 1 바이트이므로 1 증가&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[2] 배열의 효율성&lt;/span&gt;&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[2-1] 배열 연산의 시간 복잡도&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열은 모든 위치에 있는 데이터에 한번에 접근이 가능합니다. 따라서 배열에 있는 데이터에 접근하는 시간복잡도는 O(1)입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;  NOTE&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열 안에 있는 원하는 데이터를 찾아서 접근하는 것은 다른 의미입니다. 원하는 위치를 짚어서 접근한다는 게 O(1)이라는 의미입니다. 선형탐색은 O(n)입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열을 사용하게 있어서 여러 경우가 존재합니다. 배열 안에 데이터를 삽입(맨 뒤에 삽입하는 경우, 맨 앞에 삽입하는 경우, 중간에 데이터를 삽입하는 경우)할 때, 시간 복잡도를 확인하도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;(1) 맨 뒤에 삽입할 경우&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열이 &lt;code&gt;arr[5]&lt;/code&gt; 일 때, &lt;code&gt;arr[0] ~ arr[2]&lt;/code&gt; 까지만 데이터가 있는 경우에는 배열 &lt;code&gt;arr[0] ~ arr[2]에&lt;/code&gt; 있는 데이터를 고려할 필요 없이 &lt;code&gt;arr [3]&lt;/code&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;에만 &lt;/span&gt;데이터를 삽입하면 되기에 시간 복잡도는 O(1)라고 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;(2) 맨 앞에 삽입할 경우&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배열이 &lt;code&gt;arr [5] 일&lt;/code&gt; 때, 마찬가지로 &lt;code&gt;arr[0] ~ arr[2]&lt;/code&gt; 까지만 데이터가 있는 경우, 맨 앞에 데이터를 넣을 때는 기존에 있던 &lt;code&gt;arr[0] ~ arr[2]&lt;/code&gt;에 있던 데이터를 고려해야 합니다. 왜냐하면 배열의 주소 시작값이 정해져 있기에 기존에 있던 데이터를 뒤로 한 칸씩 미뤄야 하기 때문입니다. 따라서 점근표기법에 의해서 시간복잡도는 O(N)이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;(3) 중간에 삽입할 경우&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;중간에 데이터를 삽입할 경우, 중간 이후에 있는 데이터도 뒤로 미뤄야 하기에 시간 복잡도는 O(N)입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt; &amp;nbsp;IMPORTANT&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;배열을 선택할 때 고려할 점&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;할당할 수 있는 메모리 크기를 고려해야 합니다. 대부분 문제에서 메모리가 정해져 있습니다. int 형은 4바이트이고 &lt;code&gt;1kb&lt;/code&gt;는 1024바이트이고, &lt;code&gt;1MB&lt;/code&gt;는 1024KB입니다. 따라서 문제에서 메모리 제한이 128MB라고 주어졌을 때, 128MB = 128 * 1024 * 1024 / 4 면 약 3300만 개의 int 형 배열을 선언할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;맨 앞, 중간에 데이터를 삽입할 때 시간 복잡도가 O(N)입니다. 문제에서 여러 번의 삽입이 요구될 때는 많은 데이터 삽입으로 시간초과가 될 수 있으니 다른 방법이나 시간 초과를 고려해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[3] 배열 문제&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;프로그래머스의 배열 문제를 풀어보도록 하겠습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;게임 캐리터를 4가지 명령어로 움직이려고 하고, 명령어는 위, 아래, 오른쪽, 왼쪽으로 이동하고 처음 가본 길을 카운트하는게 목적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;총 명령어의 dirs 길이가 500개 정도 된다고 합니다. dirs 길이만큼 좌표를 바꿔서 visited 배열을 이용해서 처음 간 곳인지 아니면 방문했던 곳인지 확인하도록 합니다. &lt;b&gt;핵심은 가고자 하는 길이 처음 갔던 길이면 도착지에서 출발지로 다시 향하면 갔던 길로 확인하는 것이 핵심&lt;/b&gt;이라고 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;문제 링크&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a title=&quot;방문길이&quot; href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/49994?language=cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/49994?language=cpp&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1717069897843&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignLeft&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/49994?language=cpp&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bJnBnx/hyWdsFHs0B/u41FixdhAQaXO5y2uTFqB0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/sMJZa/hyWdj21G34/UtHgl5tFjZcwnlhqRQWw9k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/49994?language=cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/49994?language=cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bJnBnx/hyWdsFHs0B/u41FixdhAQaXO5y2uTFqB0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/sMJZa/hyWdj21G34/UtHgl5tFjZcwnlhqRQWw9k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

bool visited[11][11][4] = {};

int dy[] = {1, 0, -1, 0};
int dx[] = {0, -1, 0, 1};

int intDir(char c) {
  // u d l r
  if (c == 'U') {
    return 0;
  } else if (c == 'D') {
    return 2;
  }
  else if (c == 'L') {
    return 1;
  }
  else if (c == 'R') {
    return 3;
  }
}


int solution(string dirs) {   
// input value;

  int startPoint[2] = {5, 5};
  int cnt = 0;

  for (char c : dirs) {
    int dir = intDir(c);
    int nx = startPoint[0] + dx[dir];
    int ny = startPoint[1] + dy[dir];

    if (nx &amp;lt; 0 || ny &amp;lt; 0 || nx &amp;gt; 10 || ny &amp;gt; 10) continue;

    if (!visited[startPoint[0]][startPoint[1]][dir]) { 
      visited[startPoint[0]][startPoint[1]][dir] = true;
      visited[nx][ny][(dir + 2) % 4] = true;
      cnt++;
    }
    startPoint[0] = nx;
    startPoint[1] = ny;
  }

  return cnt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;  &lt;/b&gt;NOTE&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;시간 복잡도는 dirs 길이만큼 움직이므로 O(N)이라고 할 수 있겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[4] 참고문헌&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;박경록, 코딩 테스트 합격자 되기 C++편&lt;/li&gt;
&lt;li&gt;박경록 저자님의 스터디에 참가하여 정리하며 작성한 글입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/이론</category>
      <category>C++</category>
      <category>배열</category>
      <category>알고리즘</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/67</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EB%B0%B0%EC%97%B4-C-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EB%AC%B8%EC%A0%9C-%ED%8F%AC%ED%95%A8#entry67comment</comments>
      <pubDate>Thu, 30 May 2024 20:49:41 +0900</pubDate>
    </item>
    <item>
      <title>cothi</title>
      <link>https://wooong-dev.tistory.com/notice/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;교육&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터공학 전공&lt;/li&gt;
&lt;li&gt;항해 (플러스 백엔드 - TDD, 대용량 처리)&lt;/li&gt;
&lt;li&gt;케이쉴드주니어 ( &lt;span style=&quot;text-align: center;&quot;&gt;취약점 분석 트랙 )&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;코드스테이츠x빗썸 테크 캠프&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자격증&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정보보안기사&lt;/li&gt;
&lt;li&gt;정보처리기사&lt;/li&gt;
&lt;li&gt;네트워크관리사 2급&lt;/li&gt;
&lt;li&gt;컴퓨터 활용능력 1급&lt;/li&gt;
&lt;li&gt;리눅스마스터 1급 (필기)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이메일: jiungdev@gmail.com&lt;/li&gt;
&lt;li&gt;깃허브: &amp;nbsp;&lt;a href=&quot;https://github.com/cothi&quot;&gt;https://github.com/cothi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1716560498521&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;cothi - Overview&quot; data-og-description=&quot;make imagination. cothi has 6 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/cothi&quot; data-og-url=&quot;https://github.com/cothi&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mt8N9/hyV9X0kDA9/9e5dTLZoRLimILMLyuJXi1/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460&quot;&gt;&lt;a href=&quot;https://github.com/cothi&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/cothi&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mt8N9/hyV9X0kDA9/9e5dTLZoRLimILMLyuJXi1/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;cothi - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;make imagination. cothi has 6 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/notice/66</guid>
      <pubDate>Fri, 24 May 2024 22:39:11 +0900</pubDate>
    </item>
    <item>
      <title>시간복잡도 (알고리즘 문제 활용)</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1] 시간 복잡도란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 복잡도란,&lt;b&gt; 알고리즘의 성능을 나타내는 지표로써 입력 크기에 따른 연산 횟수&lt;/b&gt;를 의미합니다. 시간 복잡도가 낮으면 입력 크기가 주어졌을 때 해결하는 속도가 빠르고, 높으면 해결하는 속도가 느려집니다. 따라서 시간 복잡도는 낮을수록 좋습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1-1] 알고리즘 수행 시간을 측정하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘 수행 시간을 측정하는 방법은 &lt;b&gt;절대 시간 측정 방법&lt;/b&gt;과 &lt;b&gt;시간 복잡도&lt;/b&gt;를 측정하는 방법이 존재합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;(1) 절대시간 측정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절대 시간을 측정하는 방법은 입력 값에 따른 시간을 측정하면 됩니다. 아래 예시와 같이 &lt;code&gt;linearSearch&lt;/code&gt;에서 입력값에 따른 시간을 측정하여 절대 시간을 측정합니다. 하지만, 코드를 실행하는 환경에 따라서 달라질 수 있으므로 잘 사용하지 않는 편입니다.&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;int main() {
    vector&amp;lt;int&amp;gt; arr = {1,2,3,4,5,6};
    int target = 4;
    // 시작 시간
    auto start = chrono::high_resolution_clock::now();
    // O(n) 선형 탐색
    int result = linearSearch(arr, target);
    // 끝 시간 기록
    auto end = chrono::high_resolution_clock::now();

    // 경과 시간 계산
    chrono::duration&amp;lt;double, milli&amp;gt; elapsed = end - start;
    // 결과 출력
    cout &amp;lt;&amp;lt; &quot;Result: &quot; &amp;lt;&amp;lt; result &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;Time taken: &quot; &amp;lt;&amp;lt; elapsed.count() &amp;lt;&amp;lt; &quot; ms&quot; &amp;lt;&amp;lt; endl;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;(2) 시간 복잡도 측정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 복잡도는 입력값에 따른 결괏값이 나올 때까지의 연산 횟수로 연산 횟수는 &lt;b&gt;결과에 따라서 최선, 보통, 최악&lt;/b&gt;으로 나눌 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 앞부터 하나씩 검사하는 &lt;code&gt;linearSearch에서&lt;/code&gt; 배열이 1~10까지의 숫자가 있을 때, 1의 숫자를 찾을 때는 1번 만에 찾지만 10이라는 숫자를 찾을 때는 10번 만에 찾게 됩니다. 따라서 최선은 1, 최악은 10이라는 연산 횟수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 알고리즘 성능을 측정할 때는 다음과 같은 두 가지 고려해야 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;최악의 경우를 고려&lt;br /&gt;&lt;code&gt;linearSearch&lt;/code&gt;를 사용할 때 모든 타깃을 1번만에 찾기는 어렵다고 볼 수 있기 때문에 최악의 경우를 기준으로 시간 복잡도를 분석해야 합니다.&lt;/li&gt;
&lt;li&gt;알고리즘 성능은 연산 횟수가 아닌 추이를 활용&lt;br /&gt;목적은 제한 시간 안에 수행될 수 있는지 정도를 파악하면 충분하기에 연산 횟수가 아닌 추이를 활용하여 성능을 측정합니다. 해당 방법으로 충분히 큰 입력값 N에 따른 연산 횟수의 추이를 파악하여 시간 복잡도를 표현하는 방법을 &lt;b&gt;점근적 표기법&lt;/b&gt;이라고 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1-2] 빅오 표기법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점근적 표기법은 상한선을 활용하는 방법인데, 해당 표기법을 사용하는 것을 빅오 표기법이라고 합니다. 추이를 파악하기 때문에 함수의 최고차항을 남기고 계수를 지워 O(...)와 같이 표기합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;f(x) = 2x^5 + 3x + 4&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연산 횟수가 f(x) 라면 최고차항인 2x^5를 남기고 계수를 지워서 x^5 만을 남겨서, 결국에는 f(x)의 시간 복잡도는 O(x^5)라고 표현하게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;f(x) = 2x^5 + 3x + 4를&lt;/b&gt; C++코드로 표현하면 이렇습니다.&lt;/p&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

// f(x)
int fX(int n) {
    int cnt = 0;
    for (int i = 0; i &amp;lt; 2; i++) {
        for (int i = 0; i &amp;lt; n; i++) {
            for (int i = 0; i &amp;lt; n; i++) {
                for (int i = 0; i &amp;lt; n; i++) {
                    for (int i = 0; i &amp;lt; n; i++) {
                        for (int i = 0; i &amp;lt; n; i++) {
                            cnt++;    
                        }    
                    }
                }
            }
        }
    }
    for (int i = 0; i &amp;lt; n * 3; i++) {
        cnt++;
    }
    for (int i = 0; i &amp;lt; 4; i++) {
        cnt++;
    }
    return cnt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말한 f(x) = 2x^5 + 3x + 4는 빅오 표기법으로는 시간 복잡도가 O(x^5) 만을 남길 것입니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빅오 표기법은 왜 최고 차항만 남기고 계수를 지울까요?, 왜 이렇게 해도 되는지 &lt;/b&gt;아래의 그래프를 보며 이해하도록 하겠습니다. 아래의 그래프 그림을 통해서 여러 함수를 표현했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Drawing 2024-05-23 23.40.56.excalidraw.png&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KfaIo/btsHAM7LnAM/kMtg2lfVzyQKKpoYn4sBmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KfaIo/btsHAM7LnAM/kMtg2lfVzyQKKpoYn4sBmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KfaIo/btsHAM7LnAM/kMtg2lfVzyQKKpoYn4sBmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKfaIo%2FbtsHAM7LnAM%2FkMtg2lfVzyQKKpoYn4sBmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;693&quot; data-filename=&quot;Drawing 2024-05-23 23.40.56.excalidraw.png&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그래프대로 표현한 함수 리스트는 아래의 테이블과 같습니다.&lt;/p&gt;
&lt;table style=&quot;height: 169px; width: 339px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style16&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;th style=&quot;height: 21px; width: 34px;&quot;&gt;순서&lt;/th&gt;
&lt;th style=&quot;height: 21px; width: 80px;&quot;&gt;수식&lt;/th&gt;
&lt;th style=&quot;height: 21px; width: 225px;&quot;&gt;함수&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; width: 34px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 21px; width: 80px;&quot;&gt;y = x!&lt;/td&gt;
&lt;td style=&quot;height: 21px; width: 225px;&quot;&gt;팩토리얼 함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 34px;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 80px;&quot;&gt;y = 2^x&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 225px;&quot;&gt;지수함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 34px;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 80px;&quot;&gt;y = x^2&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 225px;&quot;&gt;다항함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 27px;&quot;&gt;
&lt;td style=&quot;height: 27px; width: 34px;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;height: 27px; width: 80px;&quot;&gt;y=xlogx&lt;/td&gt;
&lt;td style=&quot;height: 27px; width: 225px;&quot;&gt;로그함수와 다항함수의 조합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 34px;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 80px;&quot;&gt;y = x&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 225px;&quot;&gt;다항함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 34px;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 80px;&quot;&gt;y = logx&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 225px;&quot;&gt;로그함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 34px;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 80px;&quot;&gt;y=1&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 225px;&quot;&gt;상수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1번 ~ 6번&lt;/b&gt;까지 앞서 말했던 x^5는 x값이 커질수록 y 값의 격차는 천천히 증가하는 일부(3x + 4)를 무시할 수 있을 정도로 커질 것입니다. 따라서, 상한이 정확한 값이 아니라 추이를 파악하는 이유입니다. 따라서 &lt;b&gt;최고차항만을 고려해서 시간복잡도를 알아냅니다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;b&gt;알고리즘을 문제를 풀기 전에 시간 복잡도를 고려한다면 알고리즘을 생각하는 시간을 줄일 수 있습니다&lt;/b&gt;. &lt;/span&gt;백터 안에 숫자들이 정렬되어 있으면 이분 탐색법으로 O(logn)의 시간복잡도가 나오지만 , 선형 탐색으로 탐색하면 O(n)이 나오게 됩니다.&amp;nbsp; 아래의 예제를 보겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(n) - 선형탐색&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;// O(n)
int linearSearch(const vector&amp;lt;int&amp;gt;&amp;amp; arr, int target) {
	for (int i = 0; i &amp;lt; arr.size(); i++) {
		if (arr[i] == target) {
			return i; // 타겟 값을 찾으면 해당 인덱스 반환
		}
	}
	return -1; // 타겟 값을 찾지 못하면 -1 반환
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(logn) - 이분탐색&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;// 시간복잡도 O(log n)
int binarySearch(const vector&amp;lt;int&amp;gt;&amp;amp; arr, int target) {
    int left = 0;
    int right = arr.size() -1;
    while (left &amp;lt;= right) {
        int mid = (left + right) / 2;
        if (target == arr[mid]) return mid;
        if (target &amp;lt; arr[mid]) right = mid -1; 
        if (target &amp;gt; arr[mid]) left = mid + 1;
    }
    return -1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백터가 정렬되어 있으면 이분 탐색으로 탐색이 계속 반으로 줄어 탐색이 가능하게 됩니다. 이분탐색 시간복잡도를 O(logn)이라고 부릅니다.&amp;nbsp; 어떤 문제를 해결하는 알고리즘이 O(n), O(logn)의 시간 복잡도를 가질 때, O(logn)을 선택하는 게 좋을 것입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1-3] 알고리즘 활용&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절대 시간 측정은 컴퓨터 환경에 따라 달라진다고 했었습니다. 그래서, 저의 개인 컴퓨터로 연산 횟수 측정한 결과 약 10억 번 정도 연산을 하는 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;✏️ Note&lt;br /&gt;1초에 몇 번? 다양한 의견&lt;br /&gt;- https://discuss.codechef.com/t/how-many-operations-can-be-done-in-2-sec-and-3-sec/58519/3 (코드셰프)&lt;br /&gt;- https://codeforces.com/blog/entry/80680 (코드포스)&lt;br /&gt;- https://www.acmicpc.net/board/view/39001 (백준)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;위의 검색 결과, 다양한 의견이 있습니다. 1억 번 정도로 의견이 맞춰지기에 보수적으로 잡아서 C++ 기준으로 1초당 1000~3000만 번 정도라고 생각하고 알고리즘 문제 풀이에서 시간복잡도를 계산하는 것이 좋아 보입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말했듯이 계수와 나머지는 제거할 수 있을 정도로 입력값(x)이 커질수록 그래프 차이는 확연히 커지기에 일부를 계수 등을 제거할 수 있을 것입니다. 따라서&lt;b&gt;, 상한을 구하되, 최소한의 상한을 구할 필요가 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;(1) 제한 시간 1초 (3000만 번)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1초라고 가정하고 각각의 시간복잡도 테이블을 보도록 하겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;height: 161px; width: 374px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style16&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;th style=&quot;height: 21px; width: 82px;&quot;&gt;시간복잡도&lt;/th&gt;
&lt;th style=&quot;height: 21px; width: 110px;&quot;&gt;N&lt;/th&gt;
&lt;th style=&quot;height: 21px; width: 182px;&quot;&gt;최대 연산&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(N!)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;약 300만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(2^N)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;20~25&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;약 100 ~ 3000만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(N^3)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;200~300&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;약 800만 ~ 2700만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(N^2)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;3,000~5,000&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;약 900만 ~ 2500만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(NlogN)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;100만&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;약 100만 ~ 2000만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(N)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;1,000 ~ 2,000만&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;1000만 ~ 2000만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 82px;&quot;&gt;O(logN)&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 110px;&quot;&gt;10억&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 182px;&quot;&gt;30번&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(N!)&lt;br /&gt;O(N!)은 1에서 n까지 모든 자연수의 곱을 n에 상대하여 이르는 말로 기호는 느낌표(!)를 쓰며 팩토리얼이라고 읽습니다. O(N!)은 총경우의 수를 계산할 때도 쓰입니다. N! 은 N * (N-1) * (N-2) *... * 2 * 1 이 N이 라고 할 수 있습니다.&lt;/li&gt;
&lt;li&gt;O(2^N)&lt;br /&gt;O(2^N)은 입력 크기가 늘어나면 2배씩 늘어나게 됩니다. N이 3일 때에는 2 * 2 * 2으로 되어 있습니다.&lt;/li&gt;
&lt;li&gt;O(N^2)&lt;br /&gt;N에 따른 반복문이 2개 일 때 나타나게 됩니다. 예를 들면 2차원 배열을 검색할 때 사용하게 됩니다.&lt;/li&gt;
&lt;li&gt;O(logN)&lt;br /&gt;한 번 연산할 때마다 작업해야 할 양이 반으로 줄어들게 됩니다. 처음에 고민할 때 로그 밑이 없어서 의아해할 수 있는데 대부분 2로 생각하면 됩니다. 예를 들다면 2^5 =32가므로 N이 32이 일 때 5번만 탐색하면 된다는 의미입니다.&lt;/li&gt;
&lt;li&gt;O(1)&lt;br /&gt;어떤 N값이 들어와도 한 번에 구할 수 있는 경우를 말하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;✏️ Note&lt;br /&gt;위의 테이블을 전부 암기를 하는 것보다 이 정도로 생각한다라고 감을 잡는 정도로 생각하면 될 것 같습니다.&amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도를 생각하여, 알고리즘 문제를 풀어나갈 때에 자신이 짠 코드가 시간 초과가 나는지 확인하여 개선하거나, 처음에 문제를 확인하고 알고리즘을 적용할 때 시간제한을 보며, 내가 사용하려고 하는 알고리즘은 해결할 수 있는지를 확인하고 &lt;b&gt;알고리즘을 적용할 수 있기에 시간복잡도를 아는 것은 중요&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고문헌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;박경록, 「코딩 테스트 합격자 되기 C++」의 편의 스터디에 참가하여 정리하며 작성한 글입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/이론</category>
      <category>시간복잡도</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/65</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84#entry65comment</comments>
      <pubDate>Fri, 24 May 2024 13:46:20 +0900</pubDate>
    </item>
    <item>
      <title>그룹 단어 체커(1316)- C++</title>
      <link>https://wooong-dev.tistory.com/entry/%EA%B7%B8%EB%A3%B9-%EB%8B%A8%EC%96%B4-%EC%B2%B4%EC%BB%A41316-C</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1]. 그룹 단어 체커(1316)- C++&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;똑같은 스팰링이 연속해서 나타나면 그룹으로 만들고, 같은 스팰링이 떨어져 있다면, 그룹 단어가 아니기에 그룹 단어의 개수에 포함하지 않는다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[1.1]&amp;nbsp; 구현&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;aabbbccb&amp;nbsp;는 bbb, b의 같은 b의 그룹 단어가 2개 있으니 개수에 포함하지 않게 구현하면 된다.&lt;/li&gt;
&lt;li&gt;map을 이용했다. 알파벳이 소문자로 되어 있으니 크기가 26인 배열을 만들어서 arr[word[i] - 'a'] 형태로 구현하여도 된다.&lt;/li&gt;
&lt;li&gt;반복문(for) 안에서 첫 i 가 0 일 경우에는 i-1을 하지 못하지 처음 m[word[0]] = true로 초기값을 설정하여 i가 1을 시작하게 만들게 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709858774425&quot; class=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;

int t, cnt = 0;
string word;

int main() {
  // fast i/o
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(false);

  // input

  cin &amp;gt;&amp;gt; t;
  while(t--) {
    cin &amp;gt;&amp;gt; word;
    map&amp;lt;char, bool&amp;gt; m;
    m[word[0]] = true;

    bool flag = true;
    for (int i = 1; i &amp;lt; word.length(); i++) {
      if (m[word[i]] &amp;amp;&amp;amp; word[i-1] != word[i]) {
        flag = false;
        break;
      }
      m[word[i]] = true;
    }

    if (flag) cnt++;
  }

  cout &amp;lt;&amp;lt; cnt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[1.2] 결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;bull;&amp;nbsp;Accepted&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Memory:&amp;nbsp;2028&amp;nbsp;kb&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Time&amp;nbsp;&amp;nbsp;:&amp;nbsp;0&amp;nbsp;ms&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-- 문제 링크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1316&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1316&lt;/a&gt;&lt;/p&gt;</description>
      <category>알고리즘/문제</category>
      <category>Solved</category>
      <category>구현</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/63</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EA%B7%B8%EB%A3%B9-%EB%8B%A8%EC%96%B4-%EC%B2%B4%EC%BB%A41316-C#entry63comment</comments>
      <pubDate>Fri, 8 Mar 2024 09:52:56 +0900</pubDate>
    </item>
    <item>
      <title>FTP- FTP에 SSL 적용 (3/3)</title>
      <link>https://wooong-dev.tistory.com/entry/FTP-FTP%EC%97%90-ssl-%EC%A0%81%EC%9A%A9-33</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;[1] 개발 환경&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FTP (vsftpd)&lt;/li&gt;
&lt;li&gt;openssl로 인증서, 개인키 발급 - self signed certificate 방법&lt;/li&gt;
&lt;li&gt;테스트 서버 - linux (ubuntu)&lt;/li&gt;
&lt;li&gt;클라이언트 - window&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;[2] vsftpd 설정&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;[2.1] 개발환경 설치&lt;/h3&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# /bin/bash

# openssl 설치
sudo apt install openssl

# vsftpd 설치
sudo apt install vsftpd


# vsftpd 에 ssl 적용이 가능한지 확인
ldd $(which vsftpd) | grep ssl&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;openssl, vsftpd 가 설치되지 않았다면 설치를 진행합니다. 그리고 설치된 vsftpd에 ssl 이 적용할 수 있는지 확인합니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot from 2024-02-03 19-42-32.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzfM84/btsEnPywlxm/SQ83SZqN1Gdhq822Iw53X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzfM84/btsEnPywlxm/SQ83SZqN1Gdhq822Iw53X0/img.png&quot; data-alt=&quot;vsftpd 에 ssl 의존성확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzfM84/btsEnPywlxm/SQ83SZqN1Gdhq822Iw53X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzfM84%2FbtsEnPywlxm%2FSQ83SZqN1Gdhq822Iw53X0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;54&quot; data-filename=&quot;Screenshot from 2024-02-03 19-42-32.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vsftpd 에 ssl 의존성확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;br /&gt;lld 명령어는 지정한 프로그램의 의존성을 확인할 떄 사용하는 명령어이다&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;[2.2] vsftpd 설정파일 설정&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[2.2.1] vsftpd 설정&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;FTP 서버에서 active 모드로 진행하면 클라이언트에서 포트를 방화벽에서 오픈해야 하기 때문에 패시브 모드로 변경하고, SSL 활성화 그리고 SSL에 인증서와 개인키 경로를 지정합니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;# sudo vim /etc/vsconf.conf

# 인증서 위치 설정 및 ssl 활성화
rsa_cert_file=/etc/ssl/vsftpd/vsftpd.pem 
rsa_private_key_file=/etc/ssl/vsftpd/vsftpd.key
ssl_enable=YES

# 패시브 활성화 (포트 범위 10001~10010)
pasv_enable=YES
pasv_promiscuous=YES
pasv_min_port=10001
pasv_max_port=10010&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[2.2.2] vsftpd.conf 파일 설정 설명&lt;/h4&gt;
&lt;table style=&quot;height: 354px;&quot; width=&quot;907&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 25px;&quot;&gt;
&lt;th style=&quot;height: 25px;&quot;&gt;설정&lt;/th&gt;
&lt;th style=&quot;height: 25px;&quot;&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;ssl_enable&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;SSL 활성화 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;rsa_cert_file&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;SSL/TLS 인증서 위치 지정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;rsa_private_key_file&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;인증서에 대응하는 개인키 파일의 경로 지정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;ssl_tlsv1&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;SSL/TLS 프로토콜 중 TLSv1 을 사용할지 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;pasv_enable&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;패시브 모드 활성화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;pasv_min_port&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;패시브 모드 범위 최소 포트설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;pasv_max_port&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;패시브 모드 범위 최대 포트설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;pasv_promiscuous&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;같은 IP 내에서만 접속하게 하는 옵션&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;[3]. SSL 인증서 발급&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;openssl 로 self signed certificates를 발급해서 사용하려고 합니다.. 테스트 용도로 하는 것이기 때문에 이렇게 사용하는 것이라 문제가 발생하지 않지만, 따로 여러 명이서 사용하는 곳이라면 공식적인 인증서를 발급하는 편이 좋습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;[3.1] openssl 이용 발급&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# vsftpd 폴더가 없다면 생성
mkdir -f /etc/ssl/vsftpd

# openssl 인증서 발급
openssl req -x509 -nodes -days 1825 -newkey \
rsa:2048 -keyout /etc/ssl/vsftpd/vsftpd.key -out /etc/ssl/vsftpd/vsftpd.pem&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.1.1] openssl 옵션 설명&lt;/h4&gt;
&lt;table style=&quot;height: 340px;&quot; width=&quot;1133&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 24px;&quot;&gt;
&lt;th style=&quot;height: 24px;&quot;&gt;옵션&lt;/th&gt;
&lt;th style=&quot;height: 24px;&quot;&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;req&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;인증서 요청을 처리하는 서브커맨드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;x509&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;x.509&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;nodes&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;인증서의 개인 키를 암호화하지 않도록 지정하는 옵션&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;days&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;인증서의 유효 기간을 일단위로 설정하는 옵션&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;newkey&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;새로운 RSA 키 쌍을 생성하는 옵션입니다. &lt;br /&gt;rsa:2048은 2048 비트의 RSA 키를 생성하도록 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;keyout&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;개인 키를 저장한 파일 경로를 지정하는 옵션&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;out&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;생성도니 X.509 인증서를 저장할 파일 경로를 지정하는 옵션&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.1.2] openssl 질의 분석&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot from 2024-02-03 23-45-41.png&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DyoVU/btsEkDeSUWH/f0pKfWx9hZfi3Gj3dsz7m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DyoVU/btsEkDeSUWH/f0pKfWx9hZfi3Gj3dsz7m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DyoVU/btsEkDeSUWH/f0pKfWx9hZfi3Gj3dsz7m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDyoVU%2FbtsEkDeSUWH%2Ff0pKfWx9hZfi3Gj3dsz7m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;738&quot; height=&quot;302&quot; data-filename=&quot;Screenshot from 2024-02-03 23-45-41.png&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;openssl 옵션을 지정하고 입력하면 해당 질의가 나오는데 이 질의는 다음과 같다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;질의&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;작성 예제&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Country Name&lt;/td&gt;
&lt;td&gt;국가코드&lt;/td&gt;
&lt;td&gt;KR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State or Province Name&lt;/td&gt;
&lt;td&gt;시/도의 전체이름&lt;/td&gt;
&lt;td&gt;Seoul&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Locality Name&lt;/td&gt;
&lt;td&gt;시/군/구 등의 이름&lt;/td&gt;
&lt;td&gt;XXX-gu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Organization&lt;/td&gt;
&lt;td&gt;회사이름&lt;/td&gt;
&lt;td&gt;XXX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Organization Unit&lt;/td&gt;
&lt;td&gt;부서명&lt;/td&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common Name&lt;/td&gt;
&lt;td&gt;SSL 인증서를 설치할 서버의 도메인, IP&lt;/td&gt;
&lt;td&gt;테스트 목적이고 도메인이 없다면 &lt;br /&gt;사설 ip나 공인 ip를 적거나 도메인을 적어도 된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;[3] 적용 및 확인&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;[3.1] 서비스 및 확인&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.1.1] ftp 서비스 시작&lt;/h4&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# 시스템 서비스 적용 
sudo systemctl enable vsftpd

# 시스템 서비스 확인
sudo systemctl status vsftpd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot from 2024-02-04 00-28-43.png&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NFjSe/btsEmCUiW10/z4q9mmgcECf8jbdklmVJOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NFjSe/btsEmCUiW10/z4q9mmgcECf8jbdklmVJOk/img.png&quot; data-alt=&quot;vsftpd 서비스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NFjSe/btsEmCUiW10/z4q9mmgcECf8jbdklmVJOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNFjSe%2FbtsEmCUiW10%2Fz4q9mmgcECf8jbdklmVJOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;765&quot; height=&quot;219&quot; data-filename=&quot;Screenshot from 2024-02-04 00-28-43.png&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;226&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vsftpd 서비스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.1.2] 서비스 확인&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;systemctl status vsftpd&lt;/code&gt;에서 위에 그림처럼 정삭적으로 실행되고 있다면 파일질러라는 클라이언트를 통해서 FTPS를 통해서 패시브 모드가 잘 작동하고 있는지 확인하도록 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot from 2024-02-04 00-43-28.png&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/85xBF/btsEj5WZVXb/bQWTyHvbzW3MnxEHlXAie0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/85xBF/btsEj5WZVXb/bQWTyHvbzW3MnxEHlXAie0/img.png&quot; data-alt=&quot;ftp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/85xBF/btsEj5WZVXb/bQWTyHvbzW3MnxEHlXAie0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F85xBF%2FbtsEj5WZVXb%2FbQWTyHvbzW3MnxEHlXAie0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;122&quot; data-filename=&quot;Screenshot from 2024-02-04 00-43-28.png&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ftp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;클라이언트에서 접속을 하고나서 &lt;b&gt;netstat 명령어&lt;/b&gt;를 통해서 vsftpd 에서 수동 모드를 적용한 패시브 포트(10001~10010)로 데이터를 주고받는 것을 확인할 수 있습니다. 21번 포트도 vsftpd.conf 파일에서 설정(&lt;b&gt;listen_port=PORT_NUM)&lt;/b&gt;을 통해 변경할 수 있습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;[3.2] SSL 확인 및 암호화 적용 확인&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.2.1] SSL 확인&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-03 233251.png&quot; data-origin-width=&quot;1166&quot; data-origin-height=&quot;926&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VMApd/btsEjHB47k3/7BCknJWLaQbY7qmHvSYMik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VMApd/btsEjHB47k3/7BCknJWLaQbY7qmHvSYMik/img.png&quot; data-alt=&quot;접속 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VMApd/btsEjHB47k3/7BCknJWLaQbY7qmHvSYMik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVMApd%2FbtsEjHB47k3%2F7BCknJWLaQbY7qmHvSYMik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;558&quot; data-filename=&quot;스크린샷 2024-02-03 233251.png&quot; data-origin-width=&quot;1166&quot; data-origin-height=&quot;926&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;접속 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;self signed certificate 이기 때문에 경고 문구가 나옵니다. Subject 에서 이름, 기관, 국가, 시/도에서 설정한 대로 SSL 이 적용된 것을 확인할 수 있습니다. 팝업에 확인을 누르면 FTPS 서버에 접속이 가능합니다.&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.2.2] SSL 암호화 확인&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22-04 011556.png&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RQiNR/btsEkxeDdMh/ila2TerOfUUGNMdrCXg4E1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RQiNR/btsEkxeDdMh/ila2TerOfUUGNMdrCXg4E1/img.png&quot; data-alt=&quot;SSL 적용이 된 패킷&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RQiNR/btsEkxeDdMh/ila2TerOfUUGNMdrCXg4E1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRQiNR%2FbtsEkxeDdMh%2Fila2TerOfUUGNMdrCXg4E1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;797&quot; height=&quot;357&quot; data-filename=&quot;22-04 011556.png&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSL 적용이 된 패킷&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;FTPS 서버와 클라어언트간의 데이터가 와이어샤크를 통해 확인 결과 애플리케이션 데이터가 암호화되고 있는 것을 확인할 수 있다.&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;[3.2.3] SSL 암호화 적용이 안되었을 때&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5TJva/btsEkgEsJte/TqzqzlTKcdZQkXl4IuI3Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5TJva/btsEkgEsJte/TqzqzlTKcdZQkXl4IuI3Ok/img.png&quot; data-alt=&quot;SSL 적용이 안된 패킷&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5TJva/btsEkgEsJte/TqzqzlTKcdZQkXl4IuI3Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5TJva%2FbtsEkgEsJte%2FTqzqzlTKcdZQkXl4IuI3Ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;781&quot; height=&quot;188&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSL 적용이 안된 패킷&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;만약 적용되지 않는다면 파일을 주고 받을 때 위와 같이 평문 전송을 하고 스니핑 공격에 취약해질 수 있다. SSL 적용이 번거롭다면 SSH와 같은 대안이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;</description>
      <category>서버/Linux</category>
      <category>ftps</category>
      <category>SSL 적용</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/60</guid>
      <comments>https://wooong-dev.tistory.com/entry/FTP-FTP%EC%97%90-ssl-%EC%A0%81%EC%9A%A9-33#entry60comment</comments>
      <pubDate>Sun, 4 Feb 2024 01:23:21 +0900</pubDate>
    </item>
    <item>
      <title>차이를 최대로 - 10819 (C++, DFS)</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%B0%A8%EC%9D%B4%EB%A5%BC-%EC%B5%9C%EB%8C%80%EB%A1%9C-10819-C-DFS</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1]. 차이를 최대로 (C++)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[1.1] 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N개의 정수로 이루어진 배열 A가 주어진다, 적절히 정수의 순서를 바꿔 최댓값을 찾는 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[1.2] 해설&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DFS 알고리즘을 적용해서 풀어보았다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 크기가 3이고, 배열의 값이 [1, 2, 3 ] 일 경우를 생각하면 아래와 같이 총 3가지의 경우를 생각하면 구현하기 편하다&lt;b&gt;. 방문한 경우, 방문하지 않은 경우, 탐색이 트리의 끝에 방문한 경우의 DFS Tree&lt;/b&gt; 를 생각하며 코드를 구현하면 편하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot from 2024-01-28 11-54-59.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zkxCB/btsD3MoJAUh/1DfQltNp718o1N032YHcY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zkxCB/btsD3MoJAUh/1DfQltNp718o1N032YHcY0/img.png&quot; data-alt=&quot;DFS Tree&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zkxCB/btsD3MoJAUh/1DfQltNp718o1N032YHcY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzkxCB%2FbtsD3MoJAUh%2F1DfQltNp718o1N032YHcY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;406&quot; data-filename=&quot;Screenshot from 2024-01-28 11-54-59.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DFS Tree&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1). 방문한 경우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색은 이미 배열에 있는 경우이기 때문에 방문할 필요가 없다, 따라서 해당 빨간색 트리는 탐색하지 않는다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2). 방문하지 않는 경우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파란색은 방문하지 않았기에 방문하여 경우에 수를 계속해서 계산한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(3). 탐색이 트리의 끝에 방문한 경우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 그림의 경우, N이 3이 므로 Level 3에 달했을 때, 거쳐온 트리의 경우의 수의 차이를 더해서 최댓값일 경우 갱신하여 계산하면 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[1.3]. 구현&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1706411279857&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;climits&amp;gt;
#include &amp;lt;cstdlib&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#define MAX 8
using namespace std;

int n, ans = INT_MIN;
int map[MAX];
bool visit[MAX];

// dfs
void dfs(int level, vector&amp;lt;int&amp;gt; v) {
  if (level == n) {
    int v_sum = 0;
    for (int i = 0; i &amp;lt; n - 1; i++) {
      v_sum += abs(v[i] - v[i + 1]);
    }
    ans = ans &amp;gt; v_sum ? ans : v_sum;
    return;
  }

  for (int i = 0; i &amp;lt; n; i++) {
    // 방문했는지 검사
    if (visit[i])
      continue;


    visit[i] = true;
    v.push_back(map[i]);

    dfs(level + 1, v);

    visit[i] = false;
    v.pop_back();
  }
}

int main() {
  // fast i/o
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(false);

  // input
  cin &amp;gt;&amp;gt; n;
  for (int i = 0; i &amp;lt; n; i++) {
    cin &amp;gt;&amp;gt; map[i];
  }
  
  
  vector&amp;lt;int&amp;gt; v;
  dfs(0, v);

  cout &amp;lt;&amp;lt; ans;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 문제 출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10819&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/10819&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706411429515&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;10819번: 차이를 최대로&quot; data-og-description=&quot;첫째 줄에 N (3 &amp;le; N &amp;le; 8)이 주어진다. 둘째 줄에는 배열 A에 들어있는 정수가 주어진다. 배열에 들어있는 정수는 -100보다 크거나 같고, 100보다 작거나 같다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/10819&quot; data-og-url=&quot;https://www.acmicpc.net/problem/10819&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GmwZI/hyVceBentH/Foth6OyArbymEjVFeWbwl1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10819&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/10819&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GmwZI/hyVceBentH/Foth6OyArbymEjVFeWbwl1/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;10819번: 차이를 최대로&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 N (3 &amp;le; N &amp;le; 8)이 주어진다. 둘째 줄에는 배열 A에 들어있는 정수가 주어진다. 배열에 들어있는 정수는 -100보다 크거나 같고, 100보다 작거나 같다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/문제</category>
      <category>C++</category>
      <category>dfs</category>
      <category>solve</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/59</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%B0%A8%EC%9D%B4%EB%A5%BC-%EC%B5%9C%EB%8C%80%EB%A1%9C-10819-C-DFS#entry59comment</comments>
      <pubDate>Sun, 28 Jan 2024 12:10:38 +0900</pubDate>
    </item>
    <item>
      <title>ATM - 11399 (C++)</title>
      <link>https://wooong-dev.tistory.com/entry/ATM-11399-C</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;ATM&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;줄을 서 있는 사람의 수 N과 각 사람이 돈을 인출하는 데 걸리는 시간 P가 주어졌을 때, &lt;b&gt;각 사람이 돈을 인출하는데, 필요한 시간&lt;/b&gt;의 합의 최소값을 구하는 프로그램을 만들어야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 해설&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정렬이 안된 경우와 오름차순으로 정렬된 경우를 비교하면 해답을 찾을 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1). 정렬이 안된 경우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5명의 사람일 때, 핵심은 정렬이 안된 배열일 경우인 [5, 1, 2, 3, 4]를 생각해 보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 사람 -&amp;gt; 5 = 5분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 사람 -&amp;gt; &lt;b&gt;5&lt;/b&gt; + &lt;b&gt;1&lt;/b&gt; = 6분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번 사람 -&amp;gt;&lt;b&gt; 5&lt;/b&gt; + &lt;b&gt;1&lt;/b&gt; + 2 = 8분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4번 사람 -&amp;gt; &lt;b&gt;5&lt;/b&gt; +&lt;b&gt;1 &lt;/b&gt;+&lt;b&gt; 2&lt;/b&gt; + 3 = 11분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5번 사람 -&amp;gt; &lt;b&gt;5&lt;/b&gt; + &lt;b&gt;1&lt;/b&gt; + &lt;b&gt;2&lt;/b&gt; + &lt;b&gt;3&lt;/b&gt; + 4 = 15분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5 + 6 +8 + 11 + 15을 더하면 45분을 기다려야 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2). 오름차순으로 정렬된 경우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5명의 사람이 줄에 서 있을 때, 내림차순 정렬된 배열 [1, 2, 3, 4, 5]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 사람 -&amp;gt; 1 = 1분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 사람 -&amp;gt; &lt;b&gt;1&lt;/b&gt; + 2 = 3분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번 사람 -&amp;gt; &lt;b&gt;1&lt;/b&gt; + &lt;b&gt;2&lt;/b&gt; + 3 = 6분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4번 사람 -&amp;gt; &lt;b&gt;1&lt;/b&gt; + &lt;b&gt;2&lt;/b&gt; + &lt;b&gt;3&lt;/b&gt; + 4 = 10분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5번 사람 -&amp;gt; &lt;b&gt;1&lt;/b&gt; + &lt;b&gt;2&lt;/b&gt; +&lt;b&gt; 3&lt;/b&gt; + &lt;b&gt;4&lt;/b&gt; + 5 = 15분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1 + 3 + 6 + 10 + 15을 더하면 35분을 기다려야 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(3). 결론&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 수를 앞에 둘 경우, 각 사람이 돈을 인출하는데 필요한 시간이기에 각 사람마다 큰 수가 더해져 총합이 크게 나오게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 큰 수가 여러 번 더해지면 안 되기에 최솟값을 구해야 하기에 오름차순 정렬을 수행해야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 코드&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#define MAX 1001
using namespace std;

int N;
vector&amp;lt;int&amp;gt; v;
int lines[MAX] = {
    0,
};
int main() {

  cin &amp;gt;&amp;gt; N;
  int tmp;
  // 입력
  for (int i = 0; i &amp;lt; N; i++) {
    cin &amp;gt;&amp;gt; tmp;
    v.push_back(tmp);
  }

  // 오름차순 정렬
  sort(v.begin(), v.end());

  int sum = 0;
  for (int i = 0; i &amp;lt; v.size(); i++) {
    sum += v[i];
    lines[i] = sum;
  }

  int ans = 0;
  for (int i = 0; i &amp;lt; N; i++) {
    ans += lines[i];
  }
  cout &amp;lt;&amp;lt; ans;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11399&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/11399&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706408541721&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;11399번: ATM&quot; data-og-description=&quot;첫째 줄에 사람의 수 N(1 &amp;le; N &amp;le; 1,000)이 주어진다. 둘째 줄에는 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어진다. (1 &amp;le; Pi &amp;le; 1,000)&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/11399&quot; data-og-url=&quot;https://www.acmicpc.net/problem/11399&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xkcFg/hyU8ZMtH4A/BK01EE6MEHO7LQB9p6Rrn0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11399&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/11399&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xkcFg/hyU8ZMtH4A/BK01EE6MEHO7LQB9p6Rrn0/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;11399번: ATM&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 사람의 수 N(1 &amp;le; N &amp;le; 1,000)이 주어진다. 둘째 줄에는 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어진다. (1 &amp;le; Pi &amp;le; 1,000)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/문제</category>
      <category>C++</category>
      <category>Solved</category>
      <category>풀이</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/58</guid>
      <comments>https://wooong-dev.tistory.com/entry/ATM-11399-C#entry58comment</comments>
      <pubDate>Thu, 18 Jan 2024 23:11:20 +0900</pubDate>
    </item>
    <item>
      <title>2023년 회고, 앞으로 2024년 계획</title>
      <link>https://wooong-dev.tistory.com/entry/2023%EB%85%84-%ED%9A%8C%EA%B3%A0-%EC%95%9E%EC%9C%BC%EB%A1%9C-2024%EB%85%84-%EA%B3%84%ED%9A%8D</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;2023년 회고와 앞으로의 계획&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2023년 회고&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 생각보다 연간에 할 수 있는 것들은 적다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년에 적은 회고에&amp;nbsp; 적힌 것에 따르면 2023년에는 많은 도전이 필요하다고 생각해 많은 도전이 있었다.&amp;nbsp; 대학원, 자격증, 지원하고 싶은 회사에서 면접 등, 많은 도전을 했지만 도전마다 생각보다 많은 자원(시간과 돈)이 들어간다는 것을 깨달을 수 있었던 2023년도였던 것 같다. 많은 도전을 하면 각각의 도전마다 기간이 겹쳐 퀄리티가 떨어지는 것을 확인할 수 있었다. 따라서, 앞으로는 도전의 수를 줄이고 하나의 도전에 집중을 해보려고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 정보보안기사 취득&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안기사를 취득을 위해 정말 많은 시간을 쏟아부었다. 이번년도 2회 차에 합격하려 했으나 예상과는 다르게 3회 차에 합격하여서 계획이 꼬여버렸다. 결국에는 3회 차에 합격했을 때는 2회 차의 결과는 실기에는 서술형 배점 비율이 높다. 서술형에 대한 두려움이 있었지만 취득하면서 공포가 어느 정도 없어져&amp;nbsp; 기분이 좋았다. 생각보다 자격증을 공부하면서 자격증 취득도 중요하지만 과정에서 많은 것을 배울 수 있다는 것을 확인할 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 오픈소스 컨트리뷰터&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈 소스(VIM) 에 컨트리뷰터가 되었다. 컨트리뷰터가 되겠다는 일념으로 PR이 성공하자, 관심이 식어버렸다. 내가 왜 컨트리뷰터가 되려고 했는지 고민을 했고, 오픈소스 문화에 일조하기 위해서 앞으로 더욱더 관심을 가지고, 앞으로 내가 정말 관심이 있는 오픈소스 프로젝트를 선정하고 장기간 활동하려고 한다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;앞으로의 2024년 계획&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년에는 우선 순위를 두지 않고, 너무 많은 것을 펼쳐두고 다 해보려고 했었던 것 같다. 2024년에는 우선순위를 적은 일에도 확실하게 해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 코드포스 블루, 퍼플 달성하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘 공부를 다시 시작해보기로 합니다. 여러가지 이점(코딩 테스트, 데이터를 빠르게 처리하는 이점)이 있어 목표를 정해서 블루 등급이나, 퍼플 등급에 도전하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 운영체제 만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제를 만들어보기로 했다. 관련 책도 구매했다. 먼저 책에 적힌 가이드라인대로 만들어보고, 구조를 짜며 나만의 OS를 만들어보기로 한다. 추후에 어느 정도 익숙해지면 간간히 OS 포스팅도 도전하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 정보처리기사 실기 취득하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년에 정보처리기사 필기 부분을 취득하였기에, 나머지 실기를 취득하여 마무리를 지으려고한다. 내가 이것을 취득하려는 이유는 정보처리기사에 중요한 개발 지식(디자인 패턴, DB 지식 등)들이 많이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>etc/회고, 계획</category>
      <category>2023년</category>
      <category>2024년</category>
      <category>계획</category>
      <category>회고</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/57</guid>
      <comments>https://wooong-dev.tistory.com/entry/2023%EB%85%84-%ED%9A%8C%EA%B3%A0-%EC%95%9E%EC%9C%BC%EB%A1%9C-2024%EB%85%84-%EA%B3%84%ED%9A%8D#entry57comment</comments>
      <pubDate>Thu, 28 Dec 2023 05:12:48 +0900</pubDate>
    </item>
    <item>
      <title>2023년도 4회차 정보보안기사 - 최종 합격 후기</title>
      <link>https://wooong-dev.tistory.com/entry/2023%EB%85%84%EB%8F%84-4%ED%9A%8C%EC%B0%A8-%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정보보안기사 합격 후기&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 기사 실기 점수는 아래에 차트를 보면 처음은 30점대, 두 번째는 55점, 세 번째는 &lt;b&gt;64점으로 최종 합격&lt;/b&gt;하게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-21 162709.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pBKy0/btsCoFZKA7h/UBUEnfvKKBKMRYFMmKKqp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pBKy0/btsCoFZKA7h/UBUEnfvKKBKMRYFMmKKqp1/img.png&quot; data-alt=&quot;점수표&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pBKy0/btsCoFZKA7h/UBUEnfvKKBKMRYFMmKKqp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpBKy0%2FbtsCoFZKA7h%2FUBUEnfvKKBKMRYFMmKKqp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;586&quot; height=&quot;358&quot; data-filename=&quot;스크린샷 2023-12-21 162709.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;점수표&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;과정&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;필기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필기는 KISA 출제 시절에 2020년도에 한문제로 낙방하고, 포기하고 나서 다시 도전하고 싶다는 생각에 2022년도에 공부를 시작하고 2023년도 필기 1회 차에 필기를 합격했다. &lt;b&gt;이론서를 한번 정독하고 기출 문제와 알기사 필기 요약정리집를 번갈아가며 읽었다&lt;/b&gt;. 합격 점수는 정확하게 기억이 안나며 어플리케이션을 제외하고 좋은 점수를 취득한 것으로 기억한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실기 1회차&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생생하게 기억나지는 않지만, 필기를 치고 나서 기간이 적어 준비는 &lt;b&gt;알기사 책 기출문제집으로 자세히 풀지는 않고 &lt;b&gt;대략적으로 이런 문제가 있구나&amp;nbsp;&lt;/b&gt;흝어보는 느낌&lt;/b&gt;으로 봤었던 것 같다. 처음에는 합격을 생각하지도 않았고, 시험장 분위기와 시험에 감을 잡으려고 시험을 쳤었고 필기 공부를 하여 어느 정도 베이스는 잡혀있어 30점대를 기록하였다. 그래도 30점 정도는 첫 시험 치고 괜찮았다고 생각하였다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실기 2회 차&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시험이 끝나고 난 뒤 어느 정도 시간이 남아있어서 이론을 한번 정독했고,&lt;b&gt; 알기사 강의를 결제해서 빠르게 2배속으로 들었다. 그러고 나서 이론을 한번 정독하고, 알기사 기출문제를 반복하여 풀었고&lt;/b&gt; 한 번에 끝내고자 모든 시간을 쏟아부었고, 이 정도면 되겠지 하는 심정으로 정말 열심히 했다고 생각했다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1397&quot; data-origin-height=&quot;1079&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oa8Fq/btsCpdCsGVe/xHhcULhdRgiDGYKqe1a11k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oa8Fq/btsCpdCsGVe/xHhcULhdRgiDGYKqe1a11k/img.png&quot; data-alt=&quot;엑셀에 타이밍하면서 문제별로 암기한 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oa8Fq/btsCpdCsGVe/xHhcULhdRgiDGYKqe1a11k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foa8Fq%2FbtsCpdCsGVe%2FxHhcULhdRgiDGYKqe1a11k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1397&quot; height=&quot;1079&quot; data-origin-width=&quot;1397&quot; data-origin-height=&quot;1079&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;엑셀에 타이밍하면서 문제별로 암기한 내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실기 3회 차&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2회 차 낙방하고 나서 큰 충격에 빠졌다. 자격증이 이렇게 어려웠다고? 너무 무시했다는 생각이 들었다. 내가 &lt;b&gt;기출문제만 반복해서 푸는 요행을 바라고 취득할 수 없다는 것을 깨닫고, 여러 합격자에 조언을 듣고 공부 방법을 수정&lt;/b&gt;했다. 일단 기본서를 집중하지 않은 것에 대한 실수가 가장 컸다고 최종적으로 판단하게 되었고 공부 방법을 수정하기로 했다. 수정한 방법은 정보보안기사 자격증을 취득하기 위해선 기출문제로만은 한계가 있다고 결론냈고, &lt;b&gt;기본서에 적힌&lt;/b&gt; &lt;b&gt;이론서를 여러번 읽고 이해하며, markdown 편집기로 이론들을 요약해서 정리해 나갔다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-21 164053.png&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;1247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cP4BSS/btsCr78NJQG/PnP3E5hrkbXPpRIxL5Abe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cP4BSS/btsCr78NJQG/PnP3E5hrkbXPpRIxL5Abe0/img.png&quot; data-alt=&quot;네트워크 파트, 이론 정리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cP4BSS/btsCr78NJQG/PnP3E5hrkbXPpRIxL5Abe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcP4BSS%2FbtsCr78NJQG%2FPnP3E5hrkbXPpRIxL5Abe0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1067&quot; height=&quot;1247&quot; data-filename=&quot;스크린샷 2023-12-21 164053.png&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;1247&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;네트워크 파트, 이론 정리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;애플리케이션, 네트워크, 시스템, 침해사고대응 파트들을 정리하고,&amp;nbsp; 명령어 암기는 따로 정리해서 기록해 두고&lt;/b&gt; 잠이 들기 전에 한번 더 보려고 노력했다. 하지만 이렇게 정리해도 기억나지 않는 부분이 생겨서 몇 개(DB 보안, iptables에서 FORWARD 방식 등)는 시험장에서 적지 못했다. 그래도 2회차 보다는 적어낸 것들이 훨씬 많아졌다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-21 164225.png&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9yISJ/btsCohdYEYJ/6sLMkg8QBPwdWYCwG8155K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9yISJ/btsCohdYEYJ/6sLMkg8QBPwdWYCwG8155K/img.png&quot; data-alt=&quot;명령어 암기 파트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9yISJ/btsCohdYEYJ/6sLMkg8QBPwdWYCwG8155K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9yISJ%2FbtsCohdYEYJ%2F6sLMkg8QBPwdWYCwG8155K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1120&quot; height=&quot;773&quot; data-filename=&quot;스크린샷 2023-12-21 164225.png&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;명령어 암기 파트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 되돌아보면, 내가 이렇게 노력해서 효율적으로 나한테 맞는 공부 방법을 찾아가며, 공부했던 적이 있었나 할 정도로 노력했었던 것 같다. 이렇게 자신만의 정리 노트를 만들어두면 좋은 점은 &lt;b&gt;빠르게 요약한 부분을 읽을 수 있다는 점이 가장 좋다. 참고하길 바란다. 그리고 알기사 카페에서 수많은 합격 후기를 보며 자신에게 맞는 공부방법을 찾길 바랍니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;요약 (실기 준비과정)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알기사 강의를 들으며 기본서 1회 정독 -&amp;gt; 기출 문제집 반복 -&amp;gt; 이론서를 여러번 읽으며 기본서 요약 정리&amp;nbsp; -&amp;gt; 기출 문제집을 풀며 요약 정리된 내용 읽기&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;느낀 점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 문단에서 올린 그림를 보면 점수가 우상향 하고 있다. 우상향하고 있어 보안기사를 포기하지 않고 계속 접수를 하며 준비를 했었던 것 같다. 보안기사 시험은 정말 어려웠고 많은 것을 느끼게 해줬다. 그래도 &lt;b&gt;올바른 노력한다면 취득할 수 있는 도전 가치가 있는 자격증이라고 생각한다.&amp;nbsp; 누군가가 이 글을 읽고 도움이 되었으면 좋겠다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2023-12-21 165857.png&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;315&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRJ3yj/btsCyIHgtJR/kt1FNECNdkfn21KWr0Vfb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRJ3yj/btsCyIHgtJR/kt1FNECNdkfn21KWr0Vfb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRJ3yj/btsCyIHgtJR/kt1FNECNdkfn21KWr0Vfb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRJ3yj%2FbtsCyIHgtJR%2Fkt1FNECNdkfn21KWr0Vfb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1029&quot; height=&quot;315&quot; data-filename=&quot;edited_스크린샷 2023-12-21 165857.png&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;315&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>자격증/정보보안기사</category>
      <category>기사</category>
      <category>보안기사</category>
      <category>자격증</category>
      <category>정리</category>
      <category>정보보안기사</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/56</guid>
      <comments>https://wooong-dev.tistory.com/entry/2023%EB%85%84%EB%8F%84-4%ED%9A%8C%EC%B0%A8-%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0#entry56comment</comments>
      <pubDate>Thu, 21 Dec 2023 16:57:06 +0900</pubDate>
    </item>
    <item>
      <title>정보보안기사 2023년 2회차 실기 불합격 후기</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC-2023%EB%85%84-2%ED%9A%8C%EC%B0%A8-%EC%8B%A4%EA%B8%B0-%EB%B6%88%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불합격을 통지&lt;/b&gt; 받았다. 열심히 했다고 생각했는대, 쉽지 않았다. 이번 시험 난이도가 엄청 상승했다. &lt;b&gt;합격 인원 수는 51 명&lt;/b&gt;으로 기록되었다. 합격하신 분들에게 박수를 보낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-09-01 155710.png&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mrnya/btssSCX2Reo/O66avfDLlqbp8TxgZisby1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mrnya/btssSCX2Reo/O66avfDLlqbp8TxgZisby1/img.png&quot; data-alt=&quot;불합격&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mrnya/btssSCX2Reo/O66avfDLlqbp8TxgZisby1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmrnya%2FbtssSCX2Reo%2FO66avfDLlqbp8TxgZisby1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;68&quot; data-filename=&quot;스크린샷 2023-09-01 155710.png&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;불합격&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;점수는 55점&lt;/b&gt;으로 아쉽지만, 난이도가 어려웠던 시험이기에 만족스러운 결과였다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-09-01 160159.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c45n1G/btssMBMClHq/vMlexmmBNugiyOT2SC3wvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c45n1G/btssMBMClHq/vMlexmmBNugiyOT2SC3wvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c45n1G/btssMBMClHq/vMlexmmBNugiyOT2SC3wvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc45n1G%2FbtssMBMClHq%2FvMlexmmBNugiyOT2SC3wvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;821&quot; height=&quot;252&quot; data-filename=&quot;스크린샷 2023-09-01 160159.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재도전&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실기 복원된 여러 자료를 토대로 복기한 결과, 첫 시험은 30점대, 이번 시험은 55점으로 기록되어서 그래프 상으로 점수가 우상향하는 것을 보였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-09-01 161534.png&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpKoNo/btssMPjPKNu/ZfCh0lgQMlSdTrnjdiNcf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpKoNo/btssMPjPKNu/ZfCh0lgQMlSdTrnjdiNcf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpKoNo/btssMPjPKNu/ZfCh0lgQMlSdTrnjdiNcf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpKoNo%2FbtssMPjPKNu%2FZfCh0lgQMlSdTrnjdiNcf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1072&quot; height=&quot;432&quot; data-filename=&quot;스크린샷 2023-09-01 161534.png&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 실기 3회차까지 시간이 조금 남은 관계로 다른 자격증을 취득하고 나서, 이번 합격한 분들의 후기들을 보면서&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;, 부족한 부분을 채워 나가기로 했다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;----&lt;/span&gt;&lt;/p&gt;</description>
      <category>자격증/정보보안기사</category>
      <category>실기</category>
      <category>정보보안기사</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/55</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC-2023%EB%85%84-2%ED%9A%8C%EC%B0%A8-%EC%8B%A4%EA%B8%B0-%EB%B6%88%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0#entry55comment</comments>
      <pubDate>Fri, 1 Sep 2023 16:20:01 +0900</pubDate>
    </item>
    <item>
      <title>FTP  - xferlog 로그 분석 (2/3)</title>
      <link>https://wooong-dev.tistory.com/entry/FTP-xferlog-%EB%A1%9C%EA%B7%B8-%EB%B6%84%EC%84%9D</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1] 개괄&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;FTP&lt;/code&gt; 로그는 보안 모니터링, FTP 서버 내부 문제 원인 분석, 사용 패턴 파악 등등 다양한 이유로 분석할 수 있습니다. &lt;b&gt;전체적으로 vsftpd FTP 로그 설정 및 경로와 구성&lt;/b&gt;을 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[2] FTP log 설정 및 경로&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.1] 로그 기본적인 설정&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;# sudo vim /etc/vsftpd.conf

# 업로드, 다운로드 로그를 남길 것인지?
xferlog_enable=YES

# xferlog 파일 경로 설정
xferlog_file=/var/log/vsftpd.log

# xferlog 포멧을 표준으로 설정
xferlog_std_format=YES&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;xferlog를 사용할 것인지 기본적으로 설정을 해줘야 합니다. 그리고, &lt;code&gt;sudo systemctl restart vsftpd&lt;/code&gt; 데몬을 재시작합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.2] 경로&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;xferlog&lt;/code&gt; 파일은 &lt;code&gt;vsftpd.conf&lt;/code&gt; 설정 파일에 설정한 경로(&lt;code&gt;/var/log/vsftpd.log&lt;/code&gt;)에 로그 파일이 존재한다. 내부 내용의 간략한 예시 한 가지를 가지고 와 분석을 진행하겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[3] FTP 로그 구성&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-10 20-16-18.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;30&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBguw7/btsji5pOWzQ/C2nobN4CkOeoFpKoksrO1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBguw7/btsji5pOWzQ/C2nobN4CkOeoFpKoksrO1K/img.png&quot; data-alt=&quot;FTP 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBguw7/btsji5pOWzQ/C2nobN4CkOeoFpKoksrO1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBguw7%2Fbtsji5pOWzQ%2FC2nobN4CkOeoFpKoksrO1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;30&quot; data-filename=&quot;스크린샷 2023-06-10 20-16-18.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;30&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FTP 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 사진은 로그 중에서&lt;b&gt;FTP 서버에 접속해 ftpTest.txt 파일을 다운로드하고, 남은 로그 내역&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-10 20-16-18.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;30&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lyVA9/btsjpFJtkPG/NYvqWMfjGgrggczCRDLfe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lyVA9/btsjpFJtkPG/NYvqWMfjGgrggczCRDLfe1/img.png&quot; data-alt=&quot;공간으로 나눠본 FTP 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lyVA9/btsjpFJtkPG/NYvqWMfjGgrggczCRDLfe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlyVA9%2FbtsjpFJtkPG%2FNYvqWMfjGgrggczCRDLfe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;30&quot; data-filename=&quot;스크린샷 2023-06-10 20-16-18.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;30&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공간으로 나눠본 FTP 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 공간은 차례대로&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;접속날짜(Sat Jun 10 19:45:47 2023)&lt;/li&gt;
&lt;li&gt;전송시간(1초)&lt;/li&gt;
&lt;li&gt;원격 호스트 주소(::ffff:192.168:192.168.0.35)&lt;/li&gt;
&lt;li&gt;전송된 파일의 크기 9, 전송된 파일의 경로((/home/cothi/empty/ftpTest.txt)&lt;/li&gt;
&lt;li&gt;파일의 유형(b)&lt;/li&gt;
&lt;li&gt;액션플래그(_)&lt;/li&gt;
&lt;li&gt;전송 방향(o)&lt;/li&gt;
&lt;li&gt;액세스 모드(r)&lt;/li&gt;
&lt;li&gt;사용자명(cothi)&lt;/li&gt;
&lt;li&gt;서비스명(ftp)&lt;/li&gt;
&lt;li&gt;사용자의 인증 방식(0)&lt;/li&gt;
&lt;li&gt;완료상태(c)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[3.1] xferlog 세부사항&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-10 20-16-18.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;30&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBguw7/btsji5pOWzQ/C2nobN4CkOeoFpKoksrO1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBguw7/btsji5pOWzQ/C2nobN4CkOeoFpKoksrO1K/img.png&quot; data-alt=&quot;FTP 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBguw7/btsji5pOWzQ/C2nobN4CkOeoFpKoksrO1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBguw7%2Fbtsji5pOWzQ%2FC2nobN4CkOeoFpKoksrO1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;30&quot; data-filename=&quot;스크린샷 2023-06-10 20-16-18.png&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;30&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FTP 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림를 세부적으로&lt;b&gt; 아래 도표로&lt;/b&gt; 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;로그&lt;/th&gt;
&lt;th&gt;값&lt;/th&gt;
&lt;th&gt;설명 및 유형 종류&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;전송 날짜&lt;/td&gt;
&lt;td&gt;Sat Jun 10 19:45:47 2023&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송 날짜와 시간&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전송시간(초 단위)&lt;/td&gt;
&lt;td&gt;1초&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송 시간&lt;/b&gt;은 초단위로 1초를 의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;원격 호스트 주소&lt;/td&gt;
&lt;td&gt;::ffff:192.168.0.35&lt;/td&gt;
&lt;td&gt;&lt;b&gt;원격 호스트 주소&lt;/b&gt;를 말하며, ::ffff:가 붙은 이유는 IPv4를 IPv6 주소로 표시하는 하나의 방법입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전송된 파일의 크기&lt;/td&gt;
&lt;td&gt;9 bytes&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송된 파일의 크기&lt;/b&gt;를 말합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전송 파일명&lt;/td&gt;
&lt;td&gt;/home/cothi/ftp/empty/ftpTest.txt&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송된 파일명&lt;/b&gt;을 말하며, 절대 경로로 표형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;파일의 유형&lt;/td&gt;
&lt;td&gt;binary&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송 파일 유형&lt;/b&gt;을 의미하며 종류 a - ascii, 문자 및 텍스트 b - binary, 파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;액션 플래그&lt;/td&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;&lt;b&gt;액션 플래그&lt;/b&gt;는 총 4가지가 존재하는데 _ - 어떠한 행위가 일어나지 않음 c(compressed) - 파일 압축된 형태 의미 u(uncompressed) - 파일이 압축되지 않은 경우 t(tar) - tar 파일의 형식으로 묶여 있는 경우&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전송 방향&lt;/td&gt;
&lt;td&gt;o(outgoing)&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송 방향&lt;/b&gt;을 의미합니다. i(incoming) - 서버에 파일 업로드를 의미 o(outgoing) - 파일이 서버에서 나가는 것을 의미 d(delete) - 파일을 삭제하는 것을 의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;액세스모드&lt;/td&gt;
&lt;td&gt;r(시스템의 사용자 계정)&lt;/td&gt;
&lt;td&gt;어떻게 &lt;b&gt;서버에서 접근&lt;/b&gt;하는지 액세스 모드 r - 시스템의 사용자 계정 a(anonymous) - 익명 사용자 g(guest) - 비밀번호 존재하는 게스트 계정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용자명&lt;/td&gt;
&lt;td&gt;cothi&lt;/td&gt;
&lt;td&gt;&lt;b&gt;로그인 사용자 계정명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서비스명&lt;/td&gt;
&lt;td&gt;ftp&lt;/td&gt;
&lt;td&gt;&lt;b&gt;서비스명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용자의 인증 방식&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;b&gt;사용자의 인증 방식&lt;/b&gt;을 의미하며 0 - 없는 경우 1 - RFC 1413 Authentication 인증을 사용시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;인증 사용자 ID&lt;/td&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;* - RFC 1413 Authentication 인증을 사용할 때, &lt;b&gt;인증에서 사용한 메소드의 리턴된 유저 ID 값&lt;/b&gt;이지만, _이제 잘 사용을 안함에 따라 *로 표시_합니다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;완료 상태&lt;/td&gt;
&lt;td&gt;c(complete) 완료&lt;/td&gt;
&lt;td&gt;&lt;b&gt;전송 결과에 따라 보여지는 값&lt;/b&gt; c(complete) - 전송 성공 i(incomplete) - 전송 실패&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vsftpd의 FTP 로그에 대해서 알아보았습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 ftps의 ssl(vsftpd) 설정에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;---&lt;/p&gt;</description>
      <category>서버/Linux</category>
      <category>FTP</category>
      <category>ftplog</category>
      <category>log</category>
      <category>xferlog</category>
      <category>xtp구성</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/54</guid>
      <comments>https://wooong-dev.tistory.com/entry/FTP-xferlog-%EB%A1%9C%EA%B7%B8-%EB%B6%84%EC%84%9D#entry54comment</comments>
      <pubDate>Sat, 10 Jun 2023 21:35:13 +0900</pubDate>
    </item>
    <item>
      <title>FTP - 서버 운영 (1/3)</title>
      <link>https://wooong-dev.tistory.com/entry/FTP-%EC%84%9C%EB%B2%84-%EC%9A%B4%EC%98%81-13%ED%83%84-linux</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1] 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1탄은&lt;/b&gt; 간단한 FTP 서버 운영을 알아보고, &lt;b&gt;2탄은&lt;/b&gt; FTP 서버에서 파일을 옮긴 흔적을 보는 xferlog 확인, &lt;b&gt;3탄&lt;/b&gt; 평문 취약점 보완을 위한 ssl 적용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FTP 서버를 운영하는 방법을 적기 앞서, &lt;b&gt;중요한 데이터를 FTP 서버로 사용하려고 한다면, FTP는 전송 과정이 평문으로 전송되어 데이터 노출의 취약점이 있어 &lt;code&gt;sftp&lt;/code&gt;, &lt;code&gt;ftps&lt;/code&gt;를 사용하기를 권장합니다&lt;/b&gt;. 지금은 &lt;code&gt;vsftpd(very secure file transfer protocol deamon)&lt;/code&gt;을 설치하여 &lt;code&gt;FTP 서버&lt;/code&gt;를 구성하여 파일을 전송하고 공유해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssh를 사용하고 있거나 할 줄 안다면 &lt;code&gt;sftp&lt;/code&gt;를 적용하기 빠릅니다. 현재 글에서는 &lt;code&gt;ftps&lt;/code&gt;를 적용하는 방법을 적도록 하겠습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[2] 서버 설치 및 구성&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.1] 설치&lt;/h3&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# /bin/bash

# 사용 가능한 패키지 목록 업데이트
sudo apt update

# vsftpd 설치
sudo apt install vsftpd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;vsftpd를&lt;/b&gt; 설치를 진행합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[2.2] 설정 파일 재구성&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;# /etc/vsftpd.conf
# sudo vim /etc/vsftpd.conf

# standalone 관련 설정
listen=NO

listen_ipv6=YES

# 익명 사묭 불가능
anonymous_enable=NO

# 로컬 계정 사용자 접속
local_enable=YES

# 새로운 디렉토리에 접속했을 때, 보여줄 메시지를 저장
dirmessage_enable=YES

# 로컬타임
use_localtime=YES

# ftp 로그 사용
xferlog_enable=YES

# standalone 모드에서, ftp 포트변경
# 데이터 체널
connect_from_port_20=YES


# chroot 은 change root의 약어로 root 디렉터리를 바꾼다라는 의미이다.
# 해당 옵션을 이용해서 vsftpd.chroot_list 파일안에 적힌 유저 리스트는 secure_chroot_dir
# 에 적힌 경로의 디렉터리가 최상위 디렉터리가 되어, 다른 상위 디렉터리에 접근이 불가하다.
chroot_local_user=NO
chroot_list_enable=YES

# 저자는 해당 파일에 cothi 라는 user를 기입 
chroot_list_file=/etc/vsftpd.chroot_list

# root 폴더 변경
# local_root는 적지 않아도 상관없다
# 만약 secure_chroot_dir을 설정할거면 폴더에 500 또는 555 권한을 줘야 정상적으로 접속이 가능함
# 아니면 접속 불가(error), secure_dir 용도로 사용할 것이면 local_root을 굳이 적어두지 않아도 상관없습니다.
# 단지 예시로 표현
local_root=/home/userName/ftp/empty
secure_chroot_dir=/home/userName/ftp/empty

# vsftpd에서 pam 설정 파일명으로 사용할 파일명 지정
pam_service_name=vsftpd


# 평문 전송 취약점이 생길 수 있으니, YES로 적용하는게 맞는데 3탄에서 지정하도록 할게요.
# 지금은 따로 하지 않겠습니다.
ssl_enable=NO
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;sudo vim /etc/vsftpd.conf을&lt;/code&gt; 통해서 해당 파일을 편집을 진행합니다. 해당 서버의 가이드나 보안 설정을 추가하거나 제거해도 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[3] FTP 서버 시작 및 확인&lt;/h2&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# /bin/bash

# chroot_list 빈 파일 
sudo touch /etc/vsftpd.chroot_list

# vsftpd 데몬 시작
sudo systemctl start vsftpd

# 재부팅시 vsftpd 데몬 자동 시작
sudo systemctl enable vsftpd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;code&gt;vsftpd 데몬&lt;/code&gt;이 실행됩니다. 간략하게 정상적으로 작동 중인지 확인해 봅시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-08 19-25-06.png&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diFIvn/btsjdlc4Ndp/lc8ktP5HmhzX35SBQr3zAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diFIvn/btsjdlc4Ndp/lc8ktP5HmhzX35SBQr3zAK/img.png&quot; data-alt=&quot;ftp 서버 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diFIvn/btsjdlc4Ndp/lc8ktP5HmhzX35SBQr3zAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiFIvn%2Fbtsjdlc4Ndp%2Flc8ktP5HmhzX35SBQr3zAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;997&quot; height=&quot;192&quot; data-filename=&quot;스크린샷 2023-06-08 19-25-06.png&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ftp 서버 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;netstat -tlp&lt;/code&gt; 명령어로 ftp 서버가 LISTEN 상태가 된 것을 확인할 수 있다. 권한을 555로 주게 되면, 테스트하기 까다로우니, &lt;b&gt;secure_chroot_dir&lt;/b&gt;이 설정을 해제하고, ftp 서버에서 파일을 만들어, ftp 서버에 접속을 진행해 ftp 폴더 내부에 있는 생성한 파일을 가져오겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-08 21-38-12.png&quot; data-origin-width=&quot;1349&quot; data-origin-height=&quot;708&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLaWqO/btsja5Wwhv6/a0yHXnqxRs8EHQgy9p2YPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLaWqO/btsja5Wwhv6/a0yHXnqxRs8EHQgy9p2YPK/img.png&quot; data-alt=&quot;ftp 서버 이용, 파일 다운로드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLaWqO/btsja5Wwhv6/a0yHXnqxRs8EHQgy9p2YPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLaWqO%2Fbtsja5Wwhv6%2Fa0yHXnqxRs8EHQgy9p2YPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1349&quot; height=&quot;708&quot; data-filename=&quot;스크린샷 2023-06-08 21-38-12.png&quot; data-origin-width=&quot;1349&quot; data-origin-height=&quot;708&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ftp 서버 이용, 파일 다운로드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흐름은 &lt;b&gt;ftpTest.txt라는 파일을 만들었고, ~/ftp/empty 경로에 &lt;code&gt;ftp localhost&lt;/code&gt; 명령어로 접속을 진행해 local root 경로에 있는 생성한 파일을 가져와 확인&lt;/b&gt;합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[4] 포트 포워딩&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로써, 서버가 정상적으로 실행되는 것을 확인할 수 있었습니다. 하지만 이것은 로컬 호스트에서 단순히 실행한 것이므로 외부에서 접속을 허용하려면 방화벽 및 인증 및 제어를 담당하는 21번 포트를 포워딩이 필요합니다. 데이터 채널인 20번은 포트 포워딩을 하지않는 이유는 &lt;b&gt;제어를 담당하는 21번 포트는 클라이언트에서 서버로 들어오는 입장이고, 20번 포트는 서버에서 클라이언트로 데이터가 나가는 입장이기 때문입니다.&lt;/b&gt; 하지만, NAT 환경이라면 클라이언트에서 따로 &lt;b&gt;데이터 채널 포트 포워딩을 따로 해줘야 한다는 단점&lt;/b&gt;이 생깁니다. 단점을 보완하고자 패시브 모드를 사용하기도 합니다. 현재 예시에서는 액티브 모드를 사용합니다. 따라서, 21번 포트만 포트 포워딩을 진행합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[5] 방화벽(iptables)을 사용하는 경우&lt;/h3&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# /bin/bash
# iptables -I INPUT -s source_ip -d destiantion_ip -p tcp --dport 21 -j ACCEPT
# example
iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.7 -p tcp --dport 21 -j ACCEPT&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마침&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2/3탄&lt;/b&gt;에는 &lt;code&gt;vsftpd&lt;/code&gt;를 사용하면서 남은 로그를 분석하겠습니다.&lt;br /&gt;&lt;b&gt;올바르지 않은 지식이 있거나, 잘못 기입된 지식이 있을 경우 메일로 연락&lt;/b&gt; 부탁드립니다.&lt;br /&gt;감사합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;---&lt;/p&gt;</description>
      <category>서버/Linux</category>
      <category>FTP</category>
      <category>ftp 운영</category>
      <category>FTP서버</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/53</guid>
      <comments>https://wooong-dev.tistory.com/entry/FTP-%EC%84%9C%EB%B2%84-%EC%9A%B4%EC%98%81-13%ED%83%84-linux#entry53comment</comments>
      <pubDate>Thu, 8 Jun 2023 21:50:29 +0900</pubDate>
    </item>
    <item>
      <title>정보보안기사 2023년 1회차, 실기 불합격 후기</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC-2023%EB%85%84-1%ED%9A%8C%EC%B0%A8-%EC%8B%A4%EA%B8%B0-%EB%B6%88%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웬만한 것들을 적지 못했고, 가채점해볼 필요도 없이&lt;b&gt; 불합격&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;과정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 많이 준비하지 못했다&amp;nbsp; 필기가 끝나고 가채점 기간 후, 책이 도착하고 준비기간이 3주 정도 있었는데, 기간이 짧아 한계를 정해놓고 준비를 한 것이 문제인 것 같다. 그래도 시험을 치고나서 느낀 것은 어느정도 어떻게 나오고 시간배율은 어떻게 해야하는 것을 몸소 느낄 수 있는 큰 경험이 되었다고 생각한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;회고&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 불구하고, 경험삼아 시험장에 가서 시험을 친 경험 이유로 생각보다 문제를 풀어보니 눈에 익은 것들이 들어와서 제대로 잘 준비한다면 할 수 있다는 자신감을 이번 시험을 통해 얻을 수 있을 수 있었다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 2023년 2회차가 7월 29일 ~ 8월 13일 사이인데, 제대로 준비해서 좋은 결과 얻었으면 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년도 1회차 후기, 읽어주셔서 감사합니다. 2회에는 좋은 소식으로 글 남겨볼게요!&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;---&lt;/p&gt;</description>
      <category>자격증/정보보안기사</category>
      <category>회고</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/52</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC-2023%EB%85%84-1%ED%9A%8C%EC%B0%A8-%EC%8B%A4%EA%B8%B0-%EB%B6%88%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0#entry52comment</comments>
      <pubDate>Sat, 22 Apr 2023 17:55:42 +0900</pubDate>
    </item>
    <item>
      <title>정보보안(기사, 산업기사) - CBT, PBT 합격 후기, 비교</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC-%EC%82%B0%EC%97%85%EA%B8%B0%EC%82%AC-2023-1%ED%9A%8C-%ED%95%84%EA%B8%B0%ED%95%A9%EA%B2%A9%ED%9B%84%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;산업기사와 정보보안기사를 합격했다. &lt;/b&gt;예전, 2020년에, 보안기사 시험에서 1 문제 차이로 불합격하고, 시간이 흐른 후, 다시 도전하고 싶은 생각에 접수를 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;보안기사2.png&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t6QGL/btr5t80QoI7/jatkveUQ54XOsShPCRlhvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t6QGL/btr5t80QoI7/jatkveUQ54XOsShPCRlhvK/img.png&quot; data-alt=&quot;2023년 보안기사, 산업기사 합격&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t6QGL/btr5t80QoI7/jatkveUQ54XOsShPCRlhvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft6QGL%2Fbtr5t80QoI7%2FjatkveUQ54XOsShPCRlhvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;738&quot; height=&quot;478&quot; data-filename=&quot;보안기사2.png&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023년 보안기사, 산업기사 합격&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평균 점수는 두 응시 모두 &lt;b&gt;정보보안일반과 애플리케이션보안 과목에서 비교적 좋은 점수를 얻었고&lt;/b&gt;, 산업기사는 71.25점, 기사는 66점을 기록했다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 54px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.2016%; height: 18px;&quot;&gt;시스템보안&lt;/td&gt;
&lt;td style=&quot;width: 13.7596%; height: 18px;&quot;&gt;네트워크보안&lt;/td&gt;
&lt;td style=&quot;width: 17.2482%; height: 18px;&quot;&gt;어플리케이션보안&lt;/td&gt;
&lt;td style=&quot;width: 13.7597%; height: 18px;&quot;&gt;정보보안일반&lt;/td&gt;
&lt;td style=&quot;width: 19.0311%; height: 18px;&quot;&gt;정보보안관리 및 법규&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 18px;&quot;&gt;평균&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 19px;&quot;&gt;정보보안기사&lt;/td&gt;
&lt;td style=&quot;width: 11.2016%; height: 19px;&quot;&gt;55&lt;/td&gt;
&lt;td style=&quot;width: 13.7596%; height: 19px;&quot;&gt;55&lt;/td&gt;
&lt;td style=&quot;width: 17.2482%; height: 19px;&quot;&gt;65&lt;/td&gt;
&lt;td style=&quot;width: 13.7597%; height: 19px;&quot;&gt;85&lt;/td&gt;
&lt;td style=&quot;width: 19.0311%; height: 19px;&quot;&gt;70&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 19px;&quot;&gt;66(330)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px;&quot;&gt;정보보안산업기사&lt;/td&gt;
&lt;td style=&quot;width: 11.2016%; height: 17px;&quot;&gt;60&lt;/td&gt;
&lt;td style=&quot;width: 13.7596%; height: 17px;&quot;&gt;60&lt;/td&gt;
&lt;td style=&quot;width: 17.2482%; height: 17px;&quot;&gt;85&lt;/td&gt;
&lt;td style=&quot;width: 13.7597%; height: 17px;&quot;&gt;80&lt;/td&gt;
&lt;td style=&quot;width: 19.0311%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;71.25(285)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;과정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에 KISA에서 접수했었는데, KCA에서 접수하게 되어 있었다. 준비기간은 2달 정도 소요했고, 정보보안기사를 준비하면서, &lt;b&gt;두 과목에서 제일 좋은 점수를 얻었던 이유는&amp;nbsp;애플리케이션과 정보보안 과목이 제일 와닿았고, 큰 이유는 직접 체험할 수 있었던 기회가 제일 컸었던 것 같다.&lt;/b&gt; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;교재는 알기사&lt;/b&gt;로 준비했다. 알기사 필기 책은 문제 1200제와 이론 두 권, 요약서가 있다. 강의는 따로 듣지 않았다. &lt;b&gt;이론서를 2번 정도 보고 눈에 익었을 때, 기출문제를 회독했고, 기출 - 요약서를 번갈아가며 회독&lt;/b&gt;을 돌렸던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 이해가 안갔던 부분은 암호학 부분에서 CBC, ECB와블록 암호 방식이고, 머리에 암호학을 넣으려고 하니 외워지지 않았고, 그래서 스토리 및 장단점을 파악하거나, ECB와 CBC, 같은 것들은 그림을 연상하며, 이해했었고, 개발하는 사람의 입장에서 장단점을 비교했었던 것 같다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안산업기사는 PBT, 보안기사는 CBT로 보았는데, 장단점이 있는 것 같다. KCA 공식 홈페이지 공지사항(&lt;a href=&quot;https://www.cq.or.kr/qh_quagm03_001.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.cq.or.kr/qh_quagm03_001.do&lt;/a&gt;)에 따르면 앞으로 CBT로 전환될 것 같은데, PBT로 보면 좋았던 점은 몇 번 문제가 틀렸고, 문제의 통계를 보여준다. &lt;b&gt;나의 보안산업기사 시험 통계 확인 해봤더니 정답률이 낮은 것은 틀렸고, 높은 것은 맞았다. 그래도 합격한 것을 보니, 개인적인 생각으로는 기본서에도 없는 지엽적인 것들은 공부할 때, 어느 정도는 포기하는 게 좋을 것 같기도 하다.&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;통계.png&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK1G1r/btr5D2kzQrj/CIWYgdY2DWwNQHQwPAXRkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK1G1r/btr5D2kzQrj/CIWYgdY2DWwNQHQwPAXRkk/img.png&quot; data-alt=&quot;시스템 보안 통계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK1G1r/btr5D2kzQrj/CIWYgdY2DWwNQHQwPAXRkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK1G1r%2Fbtr5D2kzQrj%2FCIWYgdY2DWwNQHQwPAXRkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;359&quot; data-filename=&quot;통계.png&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시스템 보안 통계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안기사 실기가 남았는데, 실기는 알기사 강의를 들을 생각이다. 합격하기까지 &lt;u&gt;시간이 걸리겠지만, 합격한다면, 실기 후기를 남겨볼 생각이다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;----&lt;/p&gt;</description>
      <category>자격증/정보보안기사</category>
      <category>보안기사</category>
      <category>보안산업기사</category>
      <category>후기</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/51</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%A0%95%EB%B3%B4%EB%B3%B4%EC%95%88%EA%B8%B0%EC%82%AC-%EC%82%B0%EC%97%85%EA%B8%B0%EC%82%AC-2023-1%ED%9A%8C-%ED%95%84%EA%B8%B0%ED%95%A9%EA%B2%A9%ED%9B%84%EA%B8%B0#entry51comment</comments>
      <pubDate>Thu, 23 Mar 2023 20:19:56 +0900</pubDate>
    </item>
    <item>
      <title>hyper-v 우분투, 해상도 크기제한 풀기</title>
      <link>https://wooong-dev.tistory.com/entry/hyper-v-%EC%9A%B0%EB%B6%84%ED%88%AC-%ED%95%B4%EC%83%81%EB%8F%84-%ED%81%AC%EA%B8%B0%EC%A0%9C%ED%95%9C-%ED%92%80%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무슨 이유인지, 가상화 환경인 우분투에서 해상도를 1920x1080으로 제한되어 &lt;/b&gt;&lt;b&gt;grub로 수정해도 더 높일 수 없는 현상이 있다.&amp;nbsp; 따라서, 큰 모니터를 쓰는 입장에서는 불편해서 수정이 필요했다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 실행중인 hyper-v 운영체제를 종료하고, window powershell을 관리자 권한으로 실행한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 윈도우에서 명령어 입력&lt;/p&gt;
&lt;pre id=&quot;code_1677863931545&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; Set-VMVideo -VMName 'ubuntu_22.04' -HorizontalResolution 2736 -VerticalResolution 1724 -ResolutionType Single&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 가상화 환경인 우분투 grub 파일 열기&lt;/p&gt;
&lt;pre id=&quot;code_1677864084719&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /sh/bash

sudo apt install vim
sudo vim /etc/default/grub&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. grub 파일내 해당 줄 수정&lt;/p&gt;
&lt;pre id=&quot;code_1677864192787&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 해당 줄 이렇게 수정
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet splash video=hyperv_fb:2440x1440&quot;
GRUB_CMDLINE_LINUX=&quot;quiet splash video=hyperv_fb:2440x1440&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 소스코드 업데이트, grub update&lt;/p&gt;
&lt;pre id=&quot;code_1677864235636&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# grub 수정 업데이트
sudo update-grub

# reboot
sudo reboot&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리부팅을 하니 해상도가 커졌다,&amp;nbsp; 이제 해상도를 높인 큰 화면에서 작업해보자.&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>bash</category>
      <category>hyper-v</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/50</guid>
      <comments>https://wooong-dev.tistory.com/entry/hyper-v-%EC%9A%B0%EB%B6%84%ED%88%AC-%ED%95%B4%EC%83%81%EB%8F%84-%ED%81%AC%EA%B8%B0%EC%A0%9C%ED%95%9C-%ED%92%80%EA%B8%B0#entry50comment</comments>
      <pubDate>Sat, 4 Mar 2023 02:25:02 +0900</pubDate>
    </item>
    <item>
      <title>2022년 회고 및 2023년 계획</title>
      <link>https://wooong-dev.tistory.com/entry/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-%EB%B0%8F-2023%EB%85%84-%EA%B3%84%ED%9A%8D</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2022년 회고&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-29 오전 4.03.08.png&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zX2G9/btrUMPEijyf/e05zKxioUK6BkKt7c3hX3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zX2G9/btrUMPEijyf/e05zKxioUK6BkKt7c3hX3k/img.png&quot; data-alt=&quot;커밋&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zX2G9/btrUMPEijyf/e05zKxioUK6BkKt7c3hX3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzX2G9%2FbtrUMPEijyf%2Fe05zKxioUK6BkKt7c3hX3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;939&quot; height=&quot;228&quot; data-filename=&quot;스크린샷 2022-12-29 오전 4.03.08.png&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;커밋&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2022년 최종 커밋 수 약 1100개 달성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 개발에 대한 열의 보여주고 본격적으로 시작한 2022년이 된 것 같다. &lt;b&gt;2019년을 시작으로 각각 연도마다 2번, 56번, 260번, 최종적으로 2022년 약 1100번 달성을 했다&lt;/b&gt;. 이번연도는 개발을 많이 해보고 기록을 남기는 것을 의의로 시작했던 게 좋은 성과를 보인 것 같아 기분이 좋다. 처음에는 어떻게 해야 할지 잘 모르고 그냥 막 커밋을 했었던 것 같다. 그 이후로 깃허브 커밋 컨밴션이라는 것을 발견하고 기능단위, 리팩토링, 문서 업데이트 등을 기준을 두고 개발해서 더욱 커밋에 의미를 담을 수 있고 가치가 올라간 것 같다. 나름 인기 있는 sidebar.nvim 프로젝트라던지, vim 프로젝트 등에 컨트리뷰터 해보며, 외국 개발자와 소통도 해보며 경험을 많이 해본 것 같다. 2023년에는 더욱 많은 소통과 외부 개발 경험을 더 쌓어보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2022년 단기(2~3 개월) 팀프로텍트 3회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 개발자로 커리어를 쌓으려고 생각한 뒤, 팀플잭 3회를 달성했다. 많은 개발자들과 개발을 하며 경험을 쌓았고 더 숙련도를 쌓았다. 앱개발, 웹개발, 크롬익스텐션 개발을 진행하며, 분야별로 체험을 해본 것 같았고, 내가 뭘 원하는지 하고 싶은지 경험면으로 얻은 것 같았고 더 짙어진 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2022년 외주 6회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숨고 플랫폼을 이용해서 외주를 하고 있는데, 생각보다 용돈 벌이로 시작했던 게 지속적인 요청으로 해오고 있다. electron 플랫폼을 이용해 gui로 만들어보고, python으로 앱도 만들고, google apps script로 사이드 바 개발까지 수요를 맞춰 개발했던 것 같다. 서비스를 제공했던 코드를 다시 되새겨보며 더 효율적으로 개발해왔던 것 같다. 결과는 고객이 만족해서 서비스를 제공했던 곳에서 계속 요청이 오는 것 보니 좋은 성과를 보인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;외부활동&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 누리단, 제주 코딩캠프, 코드스테이츠에서 블록체인 2기로 수강하고 활동했다. 개발에 열의를 가지고 있으신 분들을 만났고, 많은 인사이트를 얻었다. 기회가 있다면 더 많은 곳에서 활동할 수 있었으면 좋겠다. 이 중에서 가장 값진 것은 많은 곳에서 블록체인 기술을 쓰이는 것을 눈으로 확인할 수 있었던 블록체인 누리단에서 활동한 이력이지 않을까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대학원 및 취업 도전&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자로 취업과 대학원에 도전을 했었다. 서류에도 합격을 못할 줄 알았더니, 3회의 면접 기회와 대학원 서류 및 면접을 봤었다. 비록 결과는 실패로 끝났지만 서류에서 경쟁력을 가진 것을 확인하고 더욱 갈고닦으면 좋은 결과가 나올 것으로 의의를 두었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2023년 계획&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무나도 아쉬웠고, 다시 되돌아보면 후회되는 한해였던 것 같다. 뭔가 엄청 많이 했지만, 눈에 띄는 성과가 없다는 것이 아쉬웠던 것 같다. 그래서 아쉬웠던 부분은 준비해왔던 정보보안기사, 블로그 글작성 저조하고, 장기적인 개발 프로젝트가 없다는 게 아쉬움으로 보였다. 이 부분을 중점적으로 해결하고자 한다.&amp;nbsp; 또한, 취업시장에 알맞은 인재와 내가 하고자 하는 일이 무엇인지 판단하고 커리어로 이어나가는 실질적인 성과를 보여주는 2023년이 되려고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;002&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/002.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/002.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2023년 복 많이 받으세요!&lt;/b&gt;&lt;/p&gt;</description>
      <category>etc/회고, 계획</category>
      <category>2023년</category>
      <category>개발</category>
      <category>회고</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/49</guid>
      <comments>https://wooong-dev.tistory.com/entry/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-%EB%B0%8F-2023%EB%85%84-%EA%B3%84%ED%9A%8D#entry49comment</comments>
      <pubDate>Thu, 29 Dec 2022 04:34:01 +0900</pubDate>
    </item>
    <item>
      <title>오스모시스 노드 연결 및 블록 탐색기 개발 후기</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%98%A4%EC%8A%A4%EB%AA%A8%EC%8B%9C%EC%8A%A4-%EB%85%B8%EB%93%9C-%EC%97%B0%EA%B2%B0-%EB%B0%8F-%EB%B8%94%EB%A1%9D-%ED%83%90%EC%83%89%EA%B8%B0-%EA%B0%9C%EB%B0%9C-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 많은 것들이 이미 만들어져 있고, 그래서 비교적 간단하게 만들 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;1021&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWSCnI/btrRMEsdsMX/ISkYSlbUAjfiyVIkDo3nT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWSCnI/btrRMEsdsMX/ISkYSlbUAjfiyVIkDo3nT0/img.png&quot; data-alt=&quot;블록 탐색기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWSCnI/btrRMEsdsMX/ISkYSlbUAjfiyVIkDo3nT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWSCnI%2FbtrRMEsdsMX%2FISkYSlbUAjfiyVIkDo3nT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1240&quot; height=&quot;1021&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;1021&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;블록 탐색기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 노드 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 블록 탐색 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 노드에서 정보 받아오기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 크롬 익스텐션 지갑&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;노드 연결&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드 연결은 도커로 배포하여 노드 3개 각각 클라우드를 풀노드를 만들어서 연결시켰다. genesis.json에 초기 설정(거버넌스 및 수량)을 할 수 있고,&amp;nbsp; 블록 생성시간, peer 노드 또한 conifg 파일에서 수정이 가능하다. 자세한 사항은 도커 파일에 정리해두었다. 노드를 연결시키며 굉장히 편리하게 만들었으며, 많은 블록체인 메인넷들이 cosmos-sdk를 어림잡아 사용하는 이유를 알 수 있었다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 링크는 도커로 노드를 연결한 방법이다.&amp;nbsp; gcp로 각각 띄울 것이면, 도커는 필요 없고 내용에 &lt;b&gt;도커를 제외한 나머지를 참고&lt;/b&gt;하면 될 것이다. 현재는 버전 0.2인데, 추후에 조금 더 간단하게 만들어볼 의향이 있다.&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1669090090591&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Docker Hub&quot; data-og-description=&quot;&quot; data-og-host=&quot;hub.docker.com&quot; data-og-source-url=&quot;https://hub.docker.com/r/cothi/osmo-init&quot; data-og-url=&quot;https://hub.docker.com/r/cothi/osmo-init&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://hub.docker.com/r/cothi/osmo-init&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hub.docker.com/r/cothi/osmo-init&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Docker Hub&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hub.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;블록 탐색 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드를 생성하여, 각각의 노드가 블록 생성이 정상적으로 시작이 되고, 요구하는 포트 포워딩을 정상적으로 열어 두었으면, rpc, api 포트로 노드에 정보를 받을 수 있게 된다. 그렇다면 블록 탐색기를 만들 수 있는 기초가 생성이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;노드에서 정보 받아오기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 정보를 받아오려면 app.toml 파일에 cors 가 풀려있는지 확인하도록 하자. 그러고 나서 정보를 받아올 때는 총 두 가지 방법이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;rpc, api 포트로 정보를 요청하여 백엔드에 DB를 두어 저장 하 client 웹사이트에 요청 시 받아오기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;2. rpc, api 포트에 백엔드에 DB를 두지 않고 client 웹사이트에 요청 시 노드에서 정보 받아오기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;이 두 가지에서 고민을 하였는데, client 쪽에서는 웹사이트에 뿌려지는 합쳐진 정보가 client 노드에서 주는 정보와 일치하지 않기 때문에 백엔드에서 어느 정도 정보 조합이 필요하다. 그래서 1번을 선택하였고 진행하게 된다. 뿌려지는 정보는 app.toml에 swagger를 켜서 확인하거나 rpc의 엔드포인트로 요청을 할 경우 기본적으로 제공을 한다. api 버전별로도 또 다르니 밑 링크의 api docs를 확인하도록 하자. 생각보다 docs 업데이트가 잘 안 되어 있고, 직접 입력해보며 값을 찾아야 하는 부분이 많으므로, 대처하는 방법이 중요합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669091105088&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Cosmos: The Internet of Blockchains&quot; data-og-description=&quot;Cosmos is an ever-expanding ecosystem of interoperable and sovereign blockchain apps and services, built for a decentralized future.&quot; data-og-host=&quot;cosmos.network&quot; data-og-source-url=&quot;https://v1.cosmos.network/rpc/v0.41.4&quot; data-og-url=&quot;https://cosmos.network&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nnyla/hyQFbvvnIx/v1WviU0ryPW1dyI76IR8V1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=436_258_614_451,https://scrap.kakaocdn.net/dn/bzm8xP/hyQFbChOa1/64U3JgEO73Ynu18xhtsczk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=436_258_614_451&quot;&gt;&lt;a href=&quot;https://v1.cosmos.network/rpc/v0.41.4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://v1.cosmos.network/rpc/v0.41.4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nnyla/hyQFbvvnIx/v1WviU0ryPW1dyI76IR8V1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=436_258_614_451,https://scrap.kakaocdn.net/dn/bzm8xP/hyQFbChOa1/64U3JgEO73Ynu18xhtsczk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=436_258_614_451');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Cosmos: The Internet of Blockchains&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Cosmos is an ever-expanding ecosystem of interoperable and sovereign blockchain apps and services, built for a decentralized future.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cosmos.network&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;크롬 익스텐션 지갑&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;balance.png&quot; data-origin-width=&quot;345&quot; data-origin-height=&quot;565&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0WT84/btrS5hgulUq/4vSkljbVY7iXQiZvd6eyDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0WT84/btrS5hgulUq/4vSkljbVY7iXQiZvd6eyDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0WT84/btrS5hgulUq/4vSkljbVY7iXQiZvd6eyDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0WT84%2FbtrS5hgulUq%2F4vSkljbVY7iXQiZvd6eyDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;345&quot; height=&quot;565&quot; data-filename=&quot;balance.png&quot; data-origin-width=&quot;345&quot; data-origin-height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;크롬 익스텐션 지갑의 기능은 create, import, send, staking, voting으로 나눌 수 있습니다. 이는 각각 모듈은 문서에 나와있으므로 참고하여 만들어보았습니다. 하지만 문서에 나와온 대로 따라 해도 문서가 부실하거나 없는 부분이 많습니다. 각각 프로젝트마다 테스트 코드를 osmojs, cosmjs에 테스트 코드로 작성한 것들이 있으므로 소스코드 내부를 보면서 만들면 수월한 부분이 많습니다. 밑에 osmojs docs를 남겨놓겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;a href=&quot;https://docs.osmosis.zone/osmojs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.osmosis.zone/osmojs&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각만 했었던 것들을 직접 만들어본 후기로는 많은 것들이 문서 업데이트가 되지 않아서, 헤매었던 기억이 있었고 상황마다 융통성 있게 해결할 필요가 있었던 대처 방법이 필요하다는 것을 깨닫게 되었습니다. 위 방법으로 비교적 간단한 블록 탐색기와 크롬 익스텐션 지갑을 만들어 볼 수 있다. 결과물을 아래에 노션 첨부하도록 하겠습니다. 감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://calm-dryosaurus-125.notion.site/3fd13ab5996049d49954dc2b2e31418f&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://calm-dryosaurus-125.notion.site/3fd13ab5996049d49954dc2b2e31418f&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로잭트/팀</category>
      <category>노드운용</category>
      <category>블록탐색기</category>
      <category>오스모시스</category>
      <category>코스모스</category>
      <category>탠더민드</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/47</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%98%A4%EC%8A%A4%EB%AA%A8%EC%8B%9C%EC%8A%A4-%EB%85%B8%EB%93%9C-%EC%97%B0%EA%B2%B0-%EB%B0%8F-%EB%B8%94%EB%A1%9D-%ED%83%90%EC%83%89%EA%B8%B0-%EA%B0%9C%EB%B0%9C-%ED%9B%84%EA%B8%B0#entry47comment</comments>
      <pubDate>Tue, 22 Nov 2022 13:51:35 +0900</pubDate>
    </item>
    <item>
      <title>블록체인 누리단 활동 - 2</title>
      <link>https://wooong-dev.tistory.com/entry/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EB%88%84%EB%A6%AC%EB%8B%A8-%ED%99%9C%EB%8F%99-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 누리단 활동이 본격적으로 시작되었다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;선택&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체험하고 싶은 다양한 분야를 선택할 수 있는 것이 장점이였다. 나는 흥미로움을 많이 느끼던 DID 서비스를 선택하여 (공공, DID) 서비스 참여 그룹에 참여하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;참여&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 내용&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아쉽게도 1차는 온라인으로 ZOOM을 통해서 블록체인 기술로 만들어진&amp;nbsp; DID&amp;nbsp; Dapp을 개발하였고, 드론 자격증 및 교육 증명 확인서 다양한 회사에서 개발하는 것을 보고나서 많은 회사에서 기술에 도전하고 있다는 것을 확인할 수 있었다. 구현 과정에서 이미 충분히 써도 좋을 정도에 앱을 보여줬다는 것이 특징이였다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분 기술을 구현한 기업들이 여건상 블록체인 내용에 많은 풀이 내용을 보여주지 않아서, 블록체인을 이제 공부를 시작한 사람들에게는 듣기 어려운 내용이였으며, 그냥 들어야하는 다소 아쉬움이 남는 소개였다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 이제는 쓰이겠다라는 기술을 먼저 확인할 수 있으니, 가상화폐에 자극적인 기사에 집중하는게 아니라 실제로 블록체인 기술을 활용해 쓰이는 모습들을 보고, 좋은 인사이트를 얻은 것 같아 좋았고, 적극적으로 목소리를 내서 피드백을 줄 수 있다는 점 또한 장점이였다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;활동비&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 누리단 활동비로 약 10만원 정도를 지급받게 되어서, 도움이 되는 많은 목소리와 피드백을 줘야한다는 책임감 또한 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 시간이 빠르게 흘러, 이제 블록체인 누리단 활동이 끝으로 가고 있는데 마지막 활동까지 최선을 다해보려고 한다.&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends2&quot; data-emoticon-name=&quot;034&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/034.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/034.png&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;</description>
      <category>etc/활동</category>
      <category>국민참여단</category>
      <category>블록체인</category>
      <category>블록체인 누리단</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/46</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EB%88%84%EB%A6%AC%EB%8B%A8-%ED%99%9C%EB%8F%99-2#entry46comment</comments>
      <pubDate>Thu, 17 Nov 2022 20:06:40 +0900</pubDate>
    </item>
    <item>
      <title>블록체인 누리단 활동 시작</title>
      <link>https://wooong-dev.tistory.com/entry/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EB%88%84%EB%A6%AC%EB%8B%A8-%ED%99%9C%EB%8F%99-%EC%8B%9C%EC%9E%91</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;블록체인 누리단&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인에 관심이 많고 생태계에 참여하고 있는 입장에서 다양한 참여를 하고 싶어서 찾아보던 결과, KISA에서 진행하는 블록체인 국민 참여단을 진행하는 블록체인 누리단에 지원하여 경험할 수 있는 기회가 주어졌다. 간접적으로 체험할 수 있는 기회가 많았지만, 이렇게 직접적으로 현장에서 설명회를 들은 것 은 처음이었다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;블록체인 누리단&lt;br /&gt;투명성과 신뢰성을 가진 블록체인 서비스를 일반 국민이 사용하기 전에 체험해보고, 사업자와의 소통을 통해 서비스의 완성도를 높여가는 활동&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2022-09-21-15-16-41 002.jpeg&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1081&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lP0Ew/btrMIdrNifK/lPtgf4yHe5YplYKLieo6kK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lP0Ew/btrMIdrNifK/lPtgf4yHe5YplYKLieo6kK/img.jpg&quot; data-alt=&quot;블록체인 발대식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lP0Ew/btrMIdrNifK/lPtgf4yHe5YplYKLieo6kK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlP0Ew%2FbtrMIdrNifK%2FlPtgf4yHe5YplYKLieo6kK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;672&quot; height=&quot;504&quot; data-filename=&quot;KakaoTalk_Photo_2022-09-21-15-16-41 002.jpeg&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1081&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;블록체인 발대식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명회장에서 간단하게 들은 결과 활동 내용은 이렇다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;활동내용&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차, 2차로 나뉘어지는데, &lt;b&gt;1차에서는&lt;/b&gt; 온라인(ZOOM)으로 베타버전인 서비스를 체험해보고 활동 수당 10만원이 주어지고, &lt;b&gt;2차에서는&lt;/b&gt; 온라인 또는 현장방문으로 상용버전인 서비스를 체험해보고 이또한 활동 수당 10만원이 지급된다. 자기가 원하는 사업 내용을 선택해서 들을 수 있으며 내가 선택할 수 있는 것은 NFT, DID 사업이였다. 내가 선택한 DID 민간, 정부 1, 2차를 선택했고 구체적인 사업 내용은 다음 활동에서 적어보도록 하겠다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;후기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발대식이 평일이였지만, 다양한 사람들이 발대식에 참여했고 참여율이 높은 것으로 생각된다. 간단하게 하는 프로그램처럼 느꼈지만 나름 진성성있게 준비하고 하는 것 같아서 보기 좋았습니다. 결론은 시간이 괜찮으면 블록체인에 관심있는 분들에게 추천하고 싶다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2022-09-21-15-16-41 004.jpeg&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;1440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvlMXM/btrMEJkSzvz/3lxNwKZ1t5kM3RcovdutX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvlMXM/btrMEJkSzvz/3lxNwKZ1t5kM3RcovdutX1/img.jpg&quot; data-alt=&quot;블록체인 누리단 뱃지 발급&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvlMXM/btrMEJkSzvz/3lxNwKZ1t5kM3RcovdutX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvlMXM%2FbtrMEJkSzvz%2F3lxNwKZ1t5kM3RcovdutX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;295&quot; height=&quot;442&quot; data-filename=&quot;KakaoTalk_Photo_2022-09-21-15-16-41 004.jpeg&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;블록체인 누리단 뱃지 발급&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/활동</category>
      <category>누리단</category>
      <category>블록체인</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/45</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EB%88%84%EB%A6%AC%EB%8B%A8-%ED%99%9C%EB%8F%99-%EC%8B%9C%EC%9E%91#entry45comment</comments>
      <pubDate>Wed, 21 Sep 2022 15:29:08 +0900</pubDate>
    </item>
    <item>
      <title>2022.09.17 - 3회 스파르톤 참가</title>
      <link>https://wooong-dev.tistory.com/entry/20220917-3%ED%9A%8C-%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%86%A4-%EC%B0%B8%EA%B0%80</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스파르톤 참가&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 홍보물을 보고, 정말 기획을 잘했다라는 생각을 했다. 기념품과 참신한 기획력으로 스파르톤을 진행하는 것을 보고 참가 신청을 진행했고, 좋은 추억으로 남을 것 같다. 앞으로 이러한 이벤트가 있으면 참여을 해야겠다는 생각이 들었다! 이제 내가 참여한 경험을 시간별로 나누어 일지를 적어보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스파르톤 도구 활용내역 -&amp;nbsp; ZEP&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;23:00 ~ 06:00 사용일지&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2022. 09. 18 23:00 ~ 01:00&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광장에 모여 간단하게 스파르타 톤 소개를 진행했다(23~24). 테이블에 앉아서 간단하게 조를 짜서 다 같이 모여 간단한 자기소개와 팀 조명을 짰다. 쉽지 않은 밤샘코딩에 부담감이 줄어들 것 같은 현장감을 느낄 수 있었다. 다음 스파르톤도 참가하면 괜찮겠다라는 생각이 들었다. &lt;b&gt;우선, 하고싶은 것과 스파르톤에서 제공하는 무료강의를 해야겠다라는 생각이 우선 들었고, 목표는 두가지로 설정을 진행하기로 했다.&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스파르톤에서 제공하는 데이터 분석 분야를 강의를 먼저 듣고, 실습해보기.&lt;/li&gt;
&lt;li&gt;깃허브 오픈소스 프로잭트에 기여하기. (sidebar.nvim - 특정 부분 소스 코드 수정)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 사항은 사실 오늘안에 끝낼 수 있을지 싶다. 우선 해보기로..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-09-18 at 12.00.30 AM.png&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAs14W/btrMjCGC6Di/yvieY47xecJRhKk3mEoAU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAs14W/btrMjCGC6Di/yvieY47xecJRhKk3mEoAU0/img.png&quot; data-alt=&quot;다같이 코딩하는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAs14W/btrMjCGC6Di/yvieY47xecJRhKk3mEoAU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAs14W%2FbtrMjCGC6Di%2FyvieY47xecJRhKk3mEoAU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;330&quot; data-filename=&quot;Screen Shot 2022-09-18 at 12.00.30 AM.png&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다같이 코딩하는 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2022. 09. 18 01:00 ~ 02:00&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python 라이브러리(pandas, matplotlib)을 가져온 뒤,&amp;nbsp; 데이터 값을 x, y 축 값을 넣고, pandas를 이용해서 데이터 정렬하고, 시각화하는 것을 목표로 진행했다.&lt;/p&gt;
&lt;pre id=&quot;code_1663437320949&quot; class=&quot;routeros&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def barGraph():

    y = [1, 10, 20, 30, 20, 50, 60]
    x= [&quot;mon&quot;, &quot;tue&quot;, &quot;wed&quot;, &quot;thu&quot;, &quot;fri&quot;, &quot;sat&quot;, &quot;sun&quot;]


    plt.title(&quot;7day importance&quot;, fontsize=15)
    plt.xlabel(&quot;importance&quot;)

    df = pd.DataFrame(
            dict(
                day=x,
                values=y
                )
            ).sort_values(&quot;values&quot;)

    plt.bar('day', 'values', data=df, color='red')
    plt.show()

barGraph()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 시간이 오래걸렸다. 데이터를 어떻게 표현하고, 차트를 어떻게 그려야할지, 막대그래프로 해야할지, 선 그래프로 해야할지 부터 고민을 진행했고, 막대그래프로, 그리고 생각보다 데이터 표현이 잘된 것 같아서 느꼈던 것은 파이썬으로 짧은 코드를 이용하여 쉽게 표현할 수 있는 것을 느꼈고, 나중에 기회가 된다면 &lt;b&gt;의미있는 실제 데이터를 가져와서 분석을 해보는 것도 좋겠다라는 느낌&lt;/b&gt;이 들었다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-09-18 at 2.53.39 AM.png&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0mpRS/btrMmgvoop4/HUAqNKmeDvKIfhk3yTUMlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0mpRS/btrMmgvoop4/HUAqNKmeDvKIfhk3yTUMlk/img.png&quot; data-alt=&quot;분석 결과 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0mpRS/btrMmgvoop4/HUAqNKmeDvKIfhk3yTUMlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0mpRS%2FbtrMmgvoop4%2FHUAqNKmeDvKIfhk3yTUMlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;752&quot; height=&quot;656&quot; data-filename=&quot;Screen Shot 2022-09-18 at 2.53.39 AM.png&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;분석 결과 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2022. 09. 18 02:00 ~ 03:00&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;이벤트 게임&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스파르톤에서 주최한 다양한 게임이 있었다. 처음에는 OX 퀴즈를 진행해서 다양한 상품(?, 무언가) 주는 것 같았다. 그 중 제일 재밌었던 것은 똥피하기 게임이다. 하늘에서 떨어지는 똥을 피해서 끝까지 살아남는 사람이 우승한다. 정신을 차리고 게임해야해서 끝나고 나니 잠이 확 깼다. 똥피하기도 우승을 진행했다. 잠을 확실이 깨고 나니 이제 남은 업무를 해야할 일을 진행해야 할 것 같았다. &lt;b&gt;기획을 잘한 듯 하다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-09-18 at 2.41.22 AM.png&quot; data-origin-width=&quot;1958&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9OSX1/btrMkQRwveU/Lm05lWwa7PjSbnYoBooJw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9OSX1/btrMkQRwveU/Lm05lWwa7PjSbnYoBooJw1/img.png&quot; data-alt=&quot;똥피하기 게임&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9OSX1/btrMkQRwveU/Lm05lWwa7PjSbnYoBooJw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9OSX1%2FbtrMkQRwveU%2FLm05lWwa7PjSbnYoBooJw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;291&quot; data-filename=&quot;Screen Shot 2022-09-18 at 2.41.22 AM.png&quot; data-origin-width=&quot;1958&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;똥피하기 게임&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2022. 09. 18 03:00 ~ 04:00&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LUA VIM 옵션을 알아보는 시간을 가지고, 계획표를 구체화하자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 내가 수정해야할 부분을 먼저 확인하는 시간을 가졌고, 오픈소스 sidebar.lua는 루아로 쓰여져 있기 때문에, 루아 문법과,&amp;nbsp; 루아로 VIM을 작동하는 방법을 알아야 했다. LUA 문법은 이전에 봐왔던 것이기 때문에 코드 분석할 때, 모르는 부분을 구글링해서 판단하는 방법으 진행하기로 정함, 내가 건들여야 할 부분은 lua로 nvim에서 user 인풋을 받아서 디렉토리를 생성하는 부분을 수정해야 한다. 루아 가이드를 먼저 읽고 시작하는게 좋을 것 같다!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSzuMH/btrMnmoFd2p/45XGMs5pkGWkDY8bkx4HV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSzuMH/btrMnmoFd2p/45XGMs5pkGWkDY8bkx4HV0/img.png&quot; data-alt=&quot;nvim 로고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSzuMH/btrMnmoFd2p/45XGMs5pkGWkDY8bkx4HV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSzuMH%2FbtrMnmoFd2p%2F45XGMs5pkGWkDY8bkx4HV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;189&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nvim 로고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2022. 09. 18 04:00 ~ 05:00&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;nvim 루아 가이드 문서 읽기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈소스 프로잭트 루아 가이드(&lt;a href=&quot;https://github.com/nanotee/nvim-lua-guide/blob/master/doc/nvim-lua-guide.txt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/nanotee/nvim-lua-guide/blob/master/doc/nvim-lua-guide.txt&lt;/a&gt;)에 의하면 루아를 통한 방법으로써 문서 내용은&lt;b&gt; 아래와 같이 기능 별로 나눠볼 수 있을 것 같다&lt;/b&gt;.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;파일 구조에서 루아 설정 파일이 위치해야하는 곳&lt;/li&gt;
&lt;li&gt;빔스크립트에서 루아를 사용하는 방법&lt;/li&gt;
&lt;li&gt;nvim이 글로벌 변수 vim을 노출시키고 lua를 통해서 vim과 api를 통해 소통하는 방법 (inspect, regex, ui, loop, lsp, treesitter 등)&lt;/li&gt;
&lt;li&gt;vim option 다루는 방법&lt;/li&gt;
&lt;li&gt;vim 내부 변수 관리하는 방법&lt;/li&gt;
&lt;li&gt;vimscript 함수 호출&lt;/li&gt;
&lt;li&gt;단축키 맵핑 정의하는 방법&lt;/li&gt;
&lt;li&gt;여러가지 잡다한&lt;/li&gt;
&lt;/ol&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 59px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 22.907%; height: 20px;&quot;&gt;vim.loop&lt;/td&gt;
&lt;td style=&quot;width: 77.093%; height: 20px;&quot;&gt;LibUV API 노출하는 모듈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 22.907%; height: 19px;&quot;&gt;vim.lsp&lt;/td&gt;
&lt;td style=&quot;width: 77.093%; height: 19px;&quot;&gt;Built-in LSP client를 제어하는 모듈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 22.907%; height: 20px;&quot;&gt;vim.treesitter&lt;/td&gt;
&lt;td style=&quot;width: 77.093%; height: 20px;&quot;&gt;Tree-siiter 의 통합을 제어하는 모듈&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2022. 09. 18 05:00 ~ 06:00&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vim.loop에 대해서 nvim 공식 문서를 더 자세히 살펴볼 필요가 있었다. 찾아보니 생각보다 다양한 기능을 진행하는 것 같다. vim.loop는 nvim 이벤트 루프의 모든 기능을 노출할 수 있다. 이것을 로우 래벨 API이며, 기능적으로 networking, filesystem, process 관리를 뜻한다. 남은 1시간 동안, 목표한 오픈소스 기여는 연기(?)하더라도 한 걸음 걸은 것 같으니, 이제, 기능에 필요한 것을 확인하자!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 에디터 LSP에서 code completion을 제공하지 않아서 어떠한 기능을 제공하는지 한눈에 알아보기 어려워 해맸고, 공식 문서에서 사용 가능한 functions들을 확인할 수 있는 방법을 알았다&lt;/p&gt;
&lt;pre id=&quot;code_1663446084272&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 사용가능한 function 출력
lua print(vim.inspect(vim.loop))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vim.loop(&lt;a href=&quot;https://github.com/nanotee/luv-vimdocs/blob/main/doc/luv.txt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/nanotee/luv-vimdocs/blob/main/doc/luv.txt&lt;/a&gt;)에서 내가 찾던 파일 시스템 관련 기능을 모두 찾을 수 있었다. 이제 이를 이용해서 코드를 작성하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;와우!, 스파르톤 마무리&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-09-18 at 5.36.53 AM.png&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;119&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EgTj2/btrMnnVrC3c/rHk80NaaGfA7fFuzZvgKZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EgTj2/btrMnnVrC3c/rHk80NaaGfA7fFuzZvgKZk/img.png&quot; data-alt=&quot;스파르톤 스티커&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EgTj2/btrMnnVrC3c/rHk80NaaGfA7fFuzZvgKZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEgTj2%2FbtrMnnVrC3c%2FrHk80NaaGfA7fFuzZvgKZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;282&quot; height=&quot;119&quot; data-filename=&quot;Screen Shot 2022-09-18 at 5.36.53 AM.png&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;119&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스파르톤 스티커&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;시간 관계상, 마지막 2번은 아쉽게도 완성하지 못했지만, 할까 말까 생각했었던 기능을 밤샘 코딩을 통해 몰입해서 실마리를 찾을 수 있던 유의미한 시간이었다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;좋은 분들을 만나서 재미있게 스파르톤을 진행한 것 같아서 좋았다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로잭트/헤커톤</category>
      <category>가즈아</category>
      <category>밤샘코딩</category>
      <category>스파르톤</category>
      <category>혁명빔</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/44</guid>
      <comments>https://wooong-dev.tistory.com/entry/20220917-3%ED%9A%8C-%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%86%A4-%EC%B0%B8%EA%B0%80#entry44comment</comments>
      <pubDate>Sat, 17 Sep 2022 22:20:44 +0900</pubDate>
    </item>
    <item>
      <title>BEB  블록체인 2기 후기</title>
      <link>https://wooong-dev.tistory.com/entry/BEB-%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-2%EA%B8%B0-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;beb 코드스테이츠 부트캠프를 마치고, 장단점을 나열해서 내가 느꼈던 것을 적어보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 수업과 활동 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무래도 취업 목적으로 하다보니, 취업 관련해서 활동을 진행하게 된다. 공부하는 기간동안 문서를 통해서 공부하고 모르는 것은 게시판 질문이나 구글 검색을 통해서 진행한다. 내가 기본 지식을 공부하는 기간 동안에는 주로 문서와 검색을 통해서 공부를 진행하게 되었다. 또한, 기본 지식을 쌓는 기간동안에는 내용을 깊게 배우기보다는 많은 양을 넓게 보는 것을 배우는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 블록체인 네트워크를 짜는 방법은 배우지 않았고, solidity를 활용한 dapp을 만드는 방법을 배웠다. 블록체인 네트워크를 짜는 방법을 여기서 배우지 않았다는 것은 아쉬움으로 남는다. 많은 양을 배워야 할 시기에 그렇게 깊은 커리큘럼에 넣기 힘들었나보다라는 생각이 든다. 하지만 아쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 마지막 프로잭트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 프로잭트는 팀프로잭트로 진행하게 된다. 자기가 하고싶은 프로잭트를 발표를하고, 선택이 된다면, 진행되는 구조이다. 당연히 팀프로잭트를 하면서 다양한 사람들과 많은 유형의 사건이 생긴다.&amp;nbsp; 이건 어디서나 발생하는 것 같다. 또한 여기도 예외는 아니다. 그렇다보니 &lt;b&gt;좋던 나쁘던 잘 대처하는 자세&lt;/b&gt;가 필요하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 문서가 제대로 나열되어 있지 않아서, 배우기 어려웠던 것들을 블록체인 커리큘럼화해서 적용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다양한 경험을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Dapp에 특화되어 배우는 것 같다. 따라서, 블록체인을 깊게 배우지 않는 것 같아 아쉬움이 남는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 후기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배운게 많았고, 재밌었다, 블록체인 모집을 진행하고 있던데, 나중에 지원하실 분들에게 도움이 되는 글이면 좋겠습니다.&lt;/p&gt;</description>
      <category>프로잭트</category>
      <category>02기</category>
      <category>beb</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/42</guid>
      <comments>https://wooong-dev.tistory.com/entry/BEB-%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-2%EA%B8%B0-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0#entry42comment</comments>
      <pubDate>Sat, 9 Apr 2022 17:45:28 +0900</pubDate>
    </item>
    <item>
      <title>백신 did smart contract 만들어보기 (비교적 간단하게 - solidity)</title>
      <link>https://wooong-dev.tistory.com/entry/%EB%B0%B1%EC%8B%A0-%EC%8A%A4%EB%A7%88%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%9E%99%ED%8A%B8-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-%EB%B9%84%EA%B5%90%EC%A0%81-%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C-solidity</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;요구사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 만들어보기 위해서라고는 하지만, 기존에 REMIX, 이더리움 테스트 넷 Ropsten 주소와 Ropsten 가스비가 어느 정도 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용법과 가스비가 필요하신 분은 기존 사용법과 가스비 받는 방법을 적어 두었으니, 필요하신 분은 참고 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wooong-dev.tistory.com/29&quot;&gt;배포1&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://wooong-dev.tistory.com/30&quot;&gt;배포2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644386903996&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;solidity - 테스트넷 simple token 배포하기 - 1 / 2 편&quot; data-og-description=&quot;ERC-20 이론부터 배포까지 ERC-20 (Ethereum Request for Comment 20), 20은 리퀘스트 숫자입니다. 이더리움 네트워크의 개선안을 제안하는 EIPs(Ethereum Improvement Proposals) 에서 관리하는 공식 프로토콜입..&quot; data-og-host=&quot;wooong.dev&quot; data-og-source-url=&quot;https://wooong-dev.tistory.com/29&quot; data-og-url=&quot;https://wooong.dev/29&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/TMDDx/hyNljEXYl8/9jqcKOSUPRatK5BNKfcreK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cp1U4I/hyNmH5ja1M/IExIB65MkrYEsSt2xg7gX0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bLLoHK/hyNmEtXLcg/cAfbwuYZzHJtwk7dj5sVN0/img.jpg?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://wooong-dev.tistory.com/29&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wooong-dev.tistory.com/29&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/TMDDx/hyNljEXYl8/9jqcKOSUPRatK5BNKfcreK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cp1U4I/hyNmH5ja1M/IExIB65MkrYEsSt2xg7gX0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bLLoHK/hyNmEtXLcg/cAfbwuYZzHJtwk7dj5sVN0/img.jpg?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;solidity - 테스트넷 simple token 배포하기 - 1 / 2 편&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ERC-20 이론부터 배포까지 ERC-20 (Ethereum Request for Comment 20), 20은 리퀘스트 숫자입니다. 이더리움 네트워크의 개선안을 제안하는 EIPs(Ethereum Improvement Proposals) 에서 관리하는 공식 프로토콜입..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wooong.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1644386903128&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;solidity - 테스트넷 simple token 배포하기 - 2 / 2 편&quot; data-og-description=&quot;solidity - 테스트넷 simple token 배포하기 - 2 / 2 편 이번편에는 필요한 준비물이 두개 있습니다. 하나는 메타스크지갑(ropsten)이고, 둘은 remix 연동입니다. 만약 준비물이 이미 준비가 되어있다면 배포&quot; data-og-host=&quot;wooong.dev&quot; data-og-source-url=&quot;https://wooong-dev.tistory.com/30&quot; data-og-url=&quot;https://wooong.dev/30&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PngoE/hyNmEguddS/KkDudriBEubrfXv4fk29x0/img.png?width=800&amp;amp;height=184&amp;amp;face=0_0_800_184,https://scrap.kakaocdn.net/dn/l3XCe/hyNlp6jYVL/M5mPiFs4gMzbozArMlVMS0/img.png?width=800&amp;amp;height=184&amp;amp;face=0_0_800_184,https://scrap.kakaocdn.net/dn/XCih4/hyNlgatpm1/N90ktGAa2gmx74kkCLpZGK/img.png?width=1384&amp;amp;height=678&amp;amp;face=0_0_1384_678&quot;&gt;&lt;a href=&quot;https://wooong-dev.tistory.com/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wooong-dev.tistory.com/30&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PngoE/hyNmEguddS/KkDudriBEubrfXv4fk29x0/img.png?width=800&amp;amp;height=184&amp;amp;face=0_0_800_184,https://scrap.kakaocdn.net/dn/l3XCe/hyNlp6jYVL/M5mPiFs4gMzbozArMlVMS0/img.png?width=800&amp;amp;height=184&amp;amp;face=0_0_800_184,https://scrap.kakaocdn.net/dn/XCih4/hyNlgatpm1/N90ktGAa2gmx74kkCLpZGK/img.png?width=1384&amp;amp;height=678&amp;amp;face=0_0_1384_678');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;solidity - 테스트넷 simple token 배포하기 - 2 / 2 편&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;solidity - 테스트넷 simple token 배포하기 - 2 / 2 편 이번편에는 필요한 준비물이 두개 있습니다. 하나는 메타스크지갑(ropsten)이고, 둘은 remix 연동입니다. 만약 준비물이 이미 준비가 되어있다면 배포&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wooong.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;solidity code 작성&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;백신 증명에 필요한 것&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;몇 회 차인지?&lt;/li&gt;
&lt;li&gt;백신 회사는?&lt;br /&gt;(1). 아스트라제네카 전달체 백신(바이러스 벡터) AstraZeneca&lt;br /&gt;(2). 얀센 전달체 백신(바이러스 벡터) Janssen&lt;br /&gt;(3). 화이자 핵산백신(mRNA) 2회 21일 Pfizer&lt;br /&gt;(4). 모더나 핵산백신(mRNA) 2회 4주 Moderna&lt;/li&gt;
&lt;li&gt;몇회차인지?&lt;/li&gt;
&lt;li&gt;발행자?&lt;/li&gt;
&lt;li&gt;특별한 값, 신원&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;solidity 전체 코드&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.10;

contract VaccineBox {
    address private issuerAddress;
    uint256 private idCount;
    mapping(uint8 =&amp;gt; string) private vaccineEnum;

    struct Vaccine{
        uint256 id;
        address issuer;
        uint256 num;
        string vaccineType;
        string value;
    }

    mapping(address =&amp;gt; Vaccine) private vaccines;


    constructor() {
        issuerAddress = msg.sender; 
        idCount = 1;
        vaccineEnum[0] = &quot;Janssen&quot;;
        vaccineEnum[1] = &quot;Pfizer&quot;;
        vaccineEnum[2] = &quot;Moderna&quot;;
        vaccineEnum[3] = &quot;AstraZeneca&quot;;
    }

    function claimVaccine(address _vaccineAddress, uint8 _vaccineType, string calldata _value) public returns(bool){
        require(issuerAddress == msg.sender, &quot;Not Issuer&quot;);
        Vaccine storage vaccine = vaccines[_vaccineAddress];
        require(vaccine.id == 0);
        vaccine.id = idCount;
        vaccine.issuer = msg.sender;
        vaccine.vaccineType = vaccineEnum[_vaccineType];
        vaccine.num = 1;
        vaccine.value = _value;
        idCount += 1;
        return true;
    }

    function claimAddVaccine(address _vaccineAddress, uint8 _vaccineType) public returns(bool) {
        require(issuerAddress == msg.sender, &quot;Not Issuer&quot;);
        vaccines[_vaccineAddress].num += 1;
        vaccines[_vaccineAddress].vaccineType = vaccineEnum[_vaccineType]; 
        return true;
    }



    function getVaccine(address _vaccineAddress) public view returns (Vaccine memory){
        return vaccines[_vaccineAddress];
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드 해설&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;struct Certificate&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;   struct Vaccine{
        uint256 id;
        address issuer;
        uint256 num;
        string vaccineType;
        string value;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;id&lt;/code&gt;는 백신 index를 확인할 수 있는 id이며, &lt;code&gt;issuer&lt;/code&gt;는 발급자,&lt;code&gt;num&lt;/code&gt;은 몇 번째 백신인지 확인 , vaccineType은 마지막으로 어떤 회사의 백신을 맞았는지, &lt;code&gt;value&lt;/code&gt;는 정보가 들어가며, 중앙화된 서버에서 제공하는 암호화된 정보, 신원, 신원 제공자, 서명 등이 json 형태로 제공됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;claimVaccine function&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;    function claimVaccine(address _vaccineAddress, uint8 _vaccineType, string calldata _value) public returns(bool){
        require(issuerAddress == msg.sender, &quot;Not Issuer&quot;);
        Vaccine storage vaccine = vaccines[_vaccineAddress];
        require(vaccine.id == 0);
        vaccine.id = idCount;
        vaccine.issuer = msg.sender;
        vaccine.vaccineType = vaccineEnum[_vaccineType];
        vaccine.num = 1;
        vaccine.value = _value;
        idCount += 1;
        return true;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;claimVaccine&lt;/code&gt;을 통해서 발행자인지, 첫 발행인지 확인을 진행하고, 이로써 vaccineAddress와 vaccineType, _value를 받아서 초기 값을 세팅 발행을 가능하게 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. ClaimAddVaccine&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function claimAddVaccine(address _vaccineAddress, uint8 _vaccineType) public returns(bool) {
    require(issuerAddress == msg.sender, &quot;Not Issuer&quot;);
    vaccines[_vaccineAddress].num += 1;
    vaccines[_vaccineAddress].vaccineType = vaccineEnum[_vaccineType]; 
    return true;
      }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;claimAddVaccine&lt;/code&gt;은 마지막으로 맞은 백신과, 백신 횟수를 업데이트해주고 발행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. getVaccine&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function getVaccine(address _vaccineAddress) public view returns (Vaccine memory){
    return vaccines[_vaccineAddress];
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;이 함수를 통해 어떠한 주체를 통하여 발행한 Vaccine&lt;/code&gt;을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스마트 컨트랙트 배포 및 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;b&gt;코드를 완성했으니, 배포하고, 사용하여&lt;/b&gt; 잘 돌아가는지 확인하는 시간을 가지겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;컴파일 및&amp;nbsp; 배포&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-09 at 2.38.37 PM.png&quot; data-origin-width=&quot;2134&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/waOy7/btrsTc0f2gJ/LlRzRoGXhrRikicTgz3xsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/waOy7/btrsTc0f2gJ/LlRzRoGXhrRikicTgz3xsk/img.png&quot; data-alt=&quot;화면1과, 화면2 (이미지 클릭 후 확대)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/waOy7/btrsTc0f2gJ/LlRzRoGXhrRikicTgz3xsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwaOy7%2FbtrsTc0f2gJ%2FLlRzRoGXhrRikicTgz3xsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;860&quot; height=&quot;289&quot; data-filename=&quot;Screen Shot 2022-02-09 at 2.38.37 PM.png&quot; data-origin-width=&quot;2134&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;화면1과, 화면2 (이미지 클릭 후 확대)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이미지가 작다면, 클릭 후 확대해주세요.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;1번&lt;/code&gt;에서는 완성했던 코드를 붙여 넣은 뒤, &lt;code&gt;2번&lt;/code&gt; 컴파일, &lt;code&gt;3번&lt;/code&gt; 배포 탭으로 이동 후, &lt;code&gt;4번&lt;/code&gt; 배포를 진행합니다.&lt;br /&gt;이제, 잘 배포가 되어있는지 확인하려면, 직접 사용도 해봐야 합니다. 사용해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-09 at 2.51.57 PM.png&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;1293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x3ZJA/btrsWT6D7Lz/LkGGdJGGiug3xnCDAWxyV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x3ZJA/btrsWT6D7Lz/LkGGdJGGiug3xnCDAWxyV0/img.png&quot; data-alt=&quot;did 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x3ZJA/btrsWT6D7Lz/LkGGdJGGiug3xnCDAWxyV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx3ZJA%2FbtrsWT6D7Lz%2FLkGGdJGGiug3xnCDAWxyV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1459&quot; height=&quot;1293&quot; data-filename=&quot;Screen Shot 2022-02-09 at 2.51.57 PM.png&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;1293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;did 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vaccine(백신 증명서)를 받을 테스트 넷 주소, 백신 타입, 그리고 값(값에는 발행 주체가 원하는 데이터가 들어있습니다), 저는 test라고 진행하겠습니다. 그리고 정상적으로 발행된 것을 확인할 수 있습니다. 한번 조회를 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;조회&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-09 at 3.05.53 PM.png&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;783&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LseId/btrsXsHAX2x/r0HDWcPKVrKPBUlrwRMTF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LseId/btrsXsHAX2x/r0HDWcPKVrKPBUlrwRMTF1/img.png&quot; data-alt=&quot;조회&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LseId/btrsXsHAX2x/r0HDWcPKVrKPBUlrwRMTF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLseId%2FbtrsXsHAX2x%2Fr0HDWcPKVrKPBUlrwRMTF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;321&quot; height=&quot;783&quot; data-filename=&quot;Screen Shot 2022-02-09 at 3.05.53 PM.png&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;783&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;조회&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정상적으로 조회가 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;회고&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막상 코드를 써보니 허술한 점이 많았습니다. 변수명이 명확하지 않다는 점, 마지막 백신만 조회되는 점, 백신 회사가 한정적이고 추가가 안 되는 점 앞으로&amp;nbsp; 수정하고 보완하여 완성도를 높여볼 생각입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한줄평&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/solidity</category>
      <category>did</category>
      <category>백신증명서</category>
      <category>증명서</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/39</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EB%B0%B1%EC%8B%A0-%EC%8A%A4%EB%A7%88%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%9E%99%ED%8A%B8-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-%EB%B9%84%EA%B5%90%EC%A0%81-%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C-solidity#entry39comment</comments>
      <pubDate>Wed, 9 Feb 2022 14:41:48 +0900</pubDate>
    </item>
    <item>
      <title>BIP-39, 니모닉 지갑 개발하기 (rest, html, cli) WITH GOLANG</title>
      <link>https://wooong-dev.tistory.com/entry/BIP-39-%EB%8B%88%EB%AA%A8%EB%8B%89-%EC%A7%80%EA%B0%91-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0-rest-html-cli-WITH-GOLANG</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;주의사항&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내용이 길어지다보니, 중구난방으로 흩어지는 느낌이 있어, 세세한 내용은 풀지 않고 넘어가려고 합니다. 하지만, &lt;code&gt;후속 포스트&lt;/code&gt;에서 내용 부분에 있어서 각각 자세히 다뤄볼 예정입니다!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;내용구성&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용방법&lt;/li&gt;
&lt;li&gt;폴더구조&lt;/li&gt;
&lt;li&gt;각각 구조에 대한 설명
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조에 대한 기본 설명&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼, 시작하도록 하겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전체적인 코드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/tetgo/wm&quot;&gt;코드&lt;/a&gt;, 링크에 들어가시면 전체적인 코드를 확인할 수 있습니다.&lt;/p&gt;
&lt;figure id=&quot;og_1644371341466&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - tetgo/wm: Command LIne Project, wallet maker with html , rest, just&quot; data-og-description=&quot;Command LIne Project, wallet maker with html , rest, just - GitHub - tetgo/wm: Command LIne Project, wallet maker with html , rest, just&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/tetgo/wm&quot; data-og-url=&quot;https://github.com/tetgo/wm&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ccKW2R/hyNlhUEeJw/4ngEQBzuZ5nKl5Ok99ZnU0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/tetgo/wm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/tetgo/wm&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ccKW2R/hyNlhUEeJw/4ngEQBzuZ5nKl5Ok99ZnU0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - tetgo/wm: Command LIne Project, wallet maker with html , rest, just&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Command LIne Project, wallet maker with html , rest, just - GitHub - tetgo/wm: Command LIne Project, wallet maker with html , rest, just&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단편적으로 글을 작성하여, 전체적인 코드를 보면서, 글을 읽는게 도움이 될 것 입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용방법&lt;/h3&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;#go가 설치되어 있어야 합니다.

# 설치
go get github.com/tetgo/wm

# 도움말 확인
wm --help

# html start, html 소스코드가 있어야하므로, 소스코드 root 폴더에서 실행해야합니다.
wm html 
# html start with setting set port
wm html --port=8000


# rest start, 
wm rest

# rest start with setting port
wm rest --port=8000&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;폴더구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-09 at 8.43.52 AM.png&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kF3bB/btrsVKVNx0j/WMuCY9h28dWkxxgGNcgC8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kF3bB/btrsVKVNx0j/WMuCY9h28dWkxxgGNcgC8K/img.png&quot; data-alt=&quot;폴더구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kF3bB/btrsVKVNx0j/WMuCY9h28dWkxxgGNcgC8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkF3bB%2FbtrsVKVNx0j%2FWMuCY9h28dWkxxgGNcgC8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1115&quot; height=&quot;293&quot; data-filename=&quot;Screen Shot 2022-02-09 at 8.43.52 AM.png&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;폴더구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴더구조는 &lt;code&gt;cli&lt;/code&gt;, &lt;code&gt;mnemonicre&lt;/code&gt;, &lt;code&gt;rest&lt;/code&gt;, &lt;code&gt;utils&lt;/code&gt;, &lt;code&gt;explorer&lt;/code&gt;로 나뉘어지게 됩니다. 각각 담당하는 부분이 있습니다.&lt;/p&gt;
&lt;table style=&quot;height: 120px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;height: 20px; width: 98.8594px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;height: 20px; width: 305.844px;&quot;&gt;사용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 84.8594px;&quot;&gt;cli&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 291.844px;&quot;&gt;옵션 값을 받아서, 어떤 것을 실행할지 알려줍니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 84.8594px;&quot;&gt;mnemonicre&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 291.844px;&quot;&gt;니모닉, 프라이빗 키, 퍼블릭 키를 생성합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 84.8594px;&quot;&gt;rest&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 291.844px;&quot;&gt;rest api 서비스를 실행합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 84.8594px;&quot;&gt;utils&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 291.844px;&quot;&gt;에러 부분을 담당합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 84.8594px;&quot;&gt;explorer&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 291.844px;&quot;&gt;html 서비스를 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표와 같이 각각 나누어 관리하기 코드를 관리하기 쉽게 나누어 봤습니다. 모든 서비스들이 mnemonicre 패키지에서 정보를 받아서 결국 client에게 전송하는 것이라고 보면 됩니다. 이제, 각각 폴더별로 소스코드의 중요한 점을 보도록 하겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;cli&lt;/h4&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;func Start() {

    switch kingpin.MustParse(app.Parse(os.Args[1:])) {
    case &quot;rest&quot;: // rest 받았을 시
        fmt.Printf(&quot;rest api start, port %d&quot;, *rPort)
        rest.Start(*rPort)

    case &quot;html&quot;: // html 받았을 시 
        explorer.Start(*hPort)

    case &quot;just&quot;: // just 받았을 시
        mnemonicre.Create(*Ent, *hPass)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;cli&lt;/code&gt; package는 소스코드의 시작점이라고 볼 수 있습니다. &lt;code&gt;Arguments&lt;/code&gt;를 받아서 Parse후에 명령어에 맞는 서비스를 시작합니다. 이때 &lt;code&gt;rest&lt;/code&gt;, &lt;code&gt;html&lt;/code&gt;은 포트번호를 따로 받거나, 기본값을 넣어주게 됩니다. &lt;code&gt;just&lt;/code&gt;는 단지 지갑을 만드는 행위입니다. 이 때 필수적으로 passphrase와 entropybit가 필수적으로 받아야합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;explorer(html)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;explorer&lt;/code&gt;는 html 서비스를 말합니다.&lt;/p&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;func home(rw http.ResponseWriter, r *http.Request) {
    data := homeData{&quot;home&quot;, false}

    switch r.Method { // method 구분
    case &quot;GET&quot;:
        templates.ExecuteTemplate(rw, &quot;home&quot;, data) // 실행

    case &quot;POST&quot;:

        // data 가져오기
        entropyBit, _ := strconv.Atoi(r.FormValue(&quot;entropyBit&quot;)) 
        passphrase := r.FormValue(&quot;passphrase&quot;)

        // 니모닉과 프라이빗, 퍼블릭 키 생성
        a, b, c := mnemonicre.Create(entropyBit, passphrase)
        mnemonicBody := Mnemonic{
            PageTitle:  &quot;home&quot;,
            Mnemonic:   a,
            PrivateKey: b,
            PublicKey:  c,
            Success:    true,
        }
        templates.ExecuteTemplate(rw, &quot;home&quot;, mnemonicBody) // 생성한 데이터 전송
    }
}

func Start(port int) {
    handler := http.NewServeMux() // html hander 
    handler.HandleFunc(&quot;/&quot;, home) 

    // html source 로드
    templates = template.Must(template.ParseGlob(templateDir + &quot;pages/*.gohtml&quot;)) 
    templates = template.Must(templates.ParseGlob(templateDir + &quot;partials/*.gohtml&quot;))
    fmt.Printf(&quot;Listening on localhost:%d\n&quot;, port)

    // 포트번호로 시작
    log.Fatal(http.ListenAndServe(fmt.Sprintf(&quot;:%d&quot;, port), handler))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj09gk/btrsVKhdFvg/2eSKE0JXJkaq7xGCgBDpT0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj09gk/btrsVKhdFvg/2eSKE0JXJkaq7xGCgBDpT0/img.gif&quot; data-alt=&quot;변경 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj09gk/btrsVKhdFvg/2eSKE0JXJkaq7xGCgBDpT0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bj09gk/btrsVKhdFvg/2eSKE0JXJkaq7xGCgBDpT0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;261&quot; data-filename=&quot;ezgif.com-gif-maker.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;변경 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;html&lt;/code&gt;은 GUI 환경을 만들어줘야하기 때문에 html 소스코드를 만들어주고, 로딩해줘야합니다. 그리고 &lt;code&gt;GET&lt;/code&gt;일 때는 아직 wallet 요청이 없기 떄문에 form을 보여줘야하고, &lt;code&gt;POST&lt;/code&gt;는 결과값을 보여줘야하기 때문에 구분짓는 로직이 필요합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;rest&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;rest&lt;/code&gt;는 기본적으로 http 프로토콜을 그대로 사용하지만, GUI로 제공하지 않고 자원만 주고 받는 형태입니다. 이때 자원은 json, xml로 주로 주고 받습니다.&lt;/p&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;func mnemonic(rw http.ResponseWriter, r *http.Request) {

    var mnemonicBody mnemonicBody
    utils.HandleErr(json.NewDecoder(r.Body).Decode(&amp;amp;mnemonicBody)) // json 데이터 받기

    entBit, _ := strconv.Atoi(mnemonicBody.EntropyBit) // 형변환
    a, b, c := mnemonicre.Create(entBit, mnemonicBody.Passphrase) // 반환 데이터 생성

    data := Mnemonic{
        Mnemonic:   a,
        PrivateKey: b,
        PublicKey:  c,
    } // 값 struct 생성

    rw.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
    rw.WriteHeader(http.StatusCreated)
    json.NewEncoder(rw).Encode(data) // json 반환

}

func Start(aPort int) {
    port = fmt.Sprintf(&quot;:%d&quot;, aPort)
    router := mux.NewRouter() // 라우터 생성
    router.HandleFunc(&quot;/&quot;, documentation).Methods(&quot;GET&quot;) // GET 요청시, 사용법 반환
    router.HandleFunc(&quot;/mnemonic&quot;, mnemonic).Methods(&quot;POST&quot;) // POST 요청시, 키, 니모닉 전송
    log.Fatal(http.ListenAndServe(port, router)) // 서비스 시작
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif.com-gif-maker (2).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Gr3x/btrsTck1Fvv/W11U3tFzqB6mveZ01dgrH1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Gr3x/btrsTck1Fvv/W11U3tFzqB6mveZ01dgrH1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Gr3x/btrsTck1Fvv/W11U3tFzqB6mveZ01dgrH1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/5Gr3x/btrsTck1Fvv/W11U3tFzqB6mveZ01dgrH1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;446&quot; data-filename=&quot;ezgif.com-gif-maker (2).gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;JSON&lt;/code&gt;형식으로 값을 주고 받는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;utils&lt;/h4&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package utils

import &quot;log&quot;

func HandleErr(err error) {
    if err != nil {
        log.Fatal(err)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;utils&lt;/code&gt;부분은 매번 error를 처리하는 로직을 적어줘야 해서, 따로 함수를 만들어주면 편해서 적어둔 것 입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;mnemonicre&lt;/h4&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package mnemonicre

import (
    &quot;fmt&quot;

    &quot;github.com/tyler-smith/go-bip32&quot;
    &quot;github.com/tyler-smith/go-bip39&quot;
)

func Create(entBit int, passphrase string) (string, string, string) {
    // Generate a mnemonic for memorization or user-friendly seeds
    entropy, _ := bip39.NewEntropy(entBit) // 엔트로피 생성
    mnemonic, _ := bip39.NewMnemonic(entropy) // 니모닉 생성

    // generate a bip39 hd wallet for the mnemonic and password
    seed := bip39.NewSeed(mnemonic, passphrase) // 시드 생성

    masterKey, _ := bip32.NewMasterKey(seed) // private key 대입
    publicKey := masterKey.PublicKey() // public key 대입

    // Display mnemonic and keys
    fmt.Println(&quot;Mnemonic: &quot;, mnemonic)
    fmt.Println(&quot;Master private key: &quot;, masterKey)
    fmt.Println(&quot;Master public key: &quot;, publicKey)


    return mnemonic, masterKey.String(), publicKey.String() // 값 반환
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/odOQu/btrsSjYMwaa/tyfB5w5ZomTeKU8WDVQaL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/odOQu/btrsSjYMwaa/tyfB5w5ZomTeKU8WDVQaL1/img.png&quot; data-alt=&quot;과정 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/odOQu/btrsSjYMwaa/tyfB5w5ZomTeKU8WDVQaL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FodOQu%2FbtrsSjYMwaa%2FtyfB5w5ZomTeKU8WDVQaL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;453&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;과정 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;128 bit으로 시작한다고 가정하고, checksum bit을 붙여서, 각 11 bit으로 나누고, 11 마다 word를 대입합니다.&amp;nbsp; 128 bit 의 ENT의 경우 4 CS(CheckSum)이고 11로 나누면 132 // 11 -&amp;gt; 12 단어가 나오게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;gherkin&quot;&gt;&lt;code&gt;CS = ENT / 32
MS = (ENT + CS) / 11

|  ENT  | CS | ENT+CS |  MS  |
+-------+----+--------+------+
|  128  |  4 |   132  |  12  |
|  160  |  5 |   165  |  15  |
|  192  |  6 |   198  |  18  |
|  224  |  7 |   231  |  21  |
|  256  |  8 |   264  |  24  |&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;용어 정리&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;entropy&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔트로피는 키 스트레칭 함수 PBKDF2를 통해서 512 비트의 시드를 만드는데 사용합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;seed&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시드는 결정론적 지갑을 구축하고 키를 파생하는 데 사용됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mnemonic&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;니모닉 코드&lt;/code&gt;는 entropy bit에 따라서 달라집니다. 각각 128, 160, 192, 224, 256 비트가 있으며, 이 니모닉 길이는 12, 15, 18, 21, 24 단어를 의미합니다.&lt;/p&gt;
&lt;pre class=&quot;gherkin&quot;&gt;&lt;code&gt;CS = ENT / 32
MS = (ENT + CS) / 11

|  ENT  | CS | ENT+CS |  MS  |
+-------+----+--------+------+
|  128  |  4 |   132  |  12  |
|  160  |  5 |   165  |  15  |
|  192  |  6 |   198  |  18  |
|  224  |  7 |   231  |  21  |
|  256  |  8 |   264  |  24  |&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reference&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- bip39&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644373307905&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - bitcoin/bips: Bitcoin Improvement Proposals&quot; data-og-description=&quot;Bitcoin Improvement Proposals. Contribute to bitcoin/bips development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&quot; data-og-url=&quot;https://github.com/bitcoin/bips&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/brDY9m/hyNlfP58VO/LgkgYmtWwFs4TqnEPRbJ71/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/brDY9m/hyNlfP58VO/LgkgYmtWwFs4TqnEPRbJ71/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - bitcoin/bips: Bitcoin Improvement Proposals&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Bitcoin Improvement Proposals. Contribute to bitcoin/bips development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- bip32&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://wiki.hash.kr/index.php/BIP32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://wiki.hash.kr/index.php/BIP32&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;회고, 고칠점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 작성하며, 완성만 생각하다보니, 내가 짠 코드 필터링 부분이 많이 허술하다고 느껴졌습니다. 예를들어서 128, 160, 192, 224, 256 엔트로비트 말고 다른 비트가 들어올 경우? 이런 점들을 개선하여 코드를 다시 수정해보는 시간을 가져봐야겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/블록체인</category>
      <category>bip32</category>
      <category>bip39</category>
      <category>Golang</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/38</guid>
      <comments>https://wooong-dev.tistory.com/entry/BIP-39-%EB%8B%88%EB%AA%A8%EB%8B%89-%EC%A7%80%EA%B0%91-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0-rest-html-cli-WITH-GOLANG#entry38comment</comments>
      <pubDate>Wed, 9 Feb 2022 11:00:27 +0900</pubDate>
    </item>
    <item>
      <title>express (nodejs) 설명</title>
      <link>https://wooong-dev.tistory.com/entry/express-nodejs-%EC%84%A4%EB%AA%85</link>
      <description>&lt;h1&gt;express&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;express&lt;/code&gt;란 Node.js를 위한 빠르고 자유로운 미니멀리즘 웹 프레임워크라고 합니다?&lt;b&gt;, http 유틸리티 메소드&lt;/b&gt; 및 &lt;b&gt;미들웨어 작성&lt;/b&gt;으로 API(Appliction Programming Interface)를 작성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;express 시작하기&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;## bash

# project 폴더 생성
mkdir test &amp;amp;&amp;amp; cd test

# package.json 생성
npm init

# express를 사용하기 위해서 설치
npm install express&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 시작하는 방법은 npm으로 시작할 시에는 위와 같이 시작하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기본 미들웨어 작성&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;import express from &quot;express&quot;

const port = 8080; //  포트 번호 설정
const app = express(); // express 객체 생성


/**
 * http method, get
 * http path, /
 * http 미들웨어 function request, response 호출
 * next 생략
 */
app.get(&quot;/&quot;, function(request, response/*, next*/) {
    response.send(&quot;hellow world&quot;); // 응답 
});

app.listen(port);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-04 at 8.16.37 PM.png&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccCOFo/btrsxF12YPw/NWj9iVRK6DLXiak8KRiRu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccCOFo/btrsxF12YPw/NWj9iVRK6DLXiak8KRiRu1/img.png&quot; data-alt=&quot;출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccCOFo/btrsxF12YPw/NWj9iVRK6DLXiak8KRiRu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccCOFo%2FbtrsxF12YPw%2FNWj9iVRK6DLXiak8KRiRu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;201&quot; data-filename=&quot;Screen Shot 2022-02-04 at 8.16.37 PM.png&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;201&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;http 메소드 get,&amp;nbsp; 경로 &quot;/&quot;을 받으면 &quot;hellow word&quot;를 응답합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;콜벡, next 이용&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import express from &quot;express&quot;

const port = 8080; //  포트 번호 설정
const app = express(); // express 객체 생성

/**
 * 요청 req
 * 응답 res
 * 미들웨어 함수에 대한 콜백 next
 */
var nextMiddle = function (req, res, next) {
   console.log(&quot;step1&quot;); // step1 출력 
    next(); // next함수 호출
}; // 미들웨어 함수 작섬


app.use(nextMiddle); // nextMiddle 사용 선언

/**
 * http method get 요청
 * 미들웨어 함수, request, respons -&amp;gt; req, res 호출
 */
app.get('/', function(req, res) {
    console.log(&quot;step2&quot;); // step 출력
    res.send('Hello World!'); // 응답
});

app.listen(port);&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-04 at 8.17.55 PM.png&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBAkcx/btrsrVyBz9X/nVPxfYJXkyfcXGPDbRrv01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBAkcx/btrsrVyBz9X/nVPxfYJXkyfcXGPDbRrv01/img.png&quot; data-alt=&quot;출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBAkcx/btrsrVyBz9X/nVPxfYJXkyfcXGPDbRrv01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBAkcx%2FbtrsrVyBz9X%2FnVPxfYJXkyfcXGPDbRrv01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;515&quot; data-filename=&quot;Screen Shot 2022-02-04 at 8.17.55 PM.png&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;callback인 next()를 사용해서&lt;b&gt; step1, step2&lt;/b&gt;를 차례대로 사용한 것을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;next 콜백, 데이터 전달&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;import express from &quot;express&quot;

const port = 8080; //  포트 번호 설정
const app = express(); // express 객체 생성

/**
 * 요청 req
 * 응답 res
 * 미들웨어 함수에 대한 콜백 next
 */
var nextMiddle = function (req, res, next) {
    req.test = &quot;전달&quot;
    next(); // next함수 호출
}; // 미들웨어 함수 작성


app.use(nextMiddle); // nextMiddle 사용 선언

/**
 * http method get 요청
 * 미들웨어 함수, request, respons -&amp;gt; req, res 호출
 */
app.get('/', function(req, res) {
    console.log(req.test); // step 출력
    res.send('Hello World!'); // 응답
});

app.listen(port);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-04 at 8.38.38 PM.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qfsZm/btrsysnRR97/M70n49Gp2LOE1oz806ehrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qfsZm/btrsysnRR97/M70n49Gp2LOE1oz806ehrk/img.png&quot; data-alt=&quot;출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qfsZm/btrsysnRR97/M70n49Gp2LOE1oz806ehrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqfsZm%2FbtrsysnRR97%2FM70n49Gp2LOE1oz806ehrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;594&quot; data-filename=&quot;Screen Shot 2022-02-04 at 8.38.38 PM.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미들웨어 함수를 지정하여 app.use(nextMiddle)을 호출했습니다. 그리고 다음 req(요청 오브젝트)를 추가하여 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로잭트</category>
      <category>Express</category>
      <category>JavaScript</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/37</guid>
      <comments>https://wooong-dev.tistory.com/entry/express-nodejs-%EC%84%A4%EB%AA%85#entry37comment</comments>
      <pubDate>Fri, 4 Feb 2022 20:41:51 +0900</pubDate>
    </item>
    <item>
      <title>SyntaxError: Cannot use import statement outside a module 해결</title>
      <link>https://wooong-dev.tistory.com/entry/SyntaxError-Cannot-use-import-statement-outside-a-module-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;h1&gt;SyntaxError: Cannot use import statement outside a module 해결&lt;code&gt;&lt;/code&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import 방법으로 외부 라이브러리를 불러올 때, 해당 문구를 출력하며, import 라이브러리를 불러오지 못하는 경우가 발생했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-03 at 7.24.46 PM.png&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cL0cl5/btrspKQo1Ma/L0p8zrF5c21zDrYlyoBQW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cL0cl5/btrspKQo1Ma/L0p8zrF5c21zDrYlyoBQW1/img.png&quot; data-alt=&quot;오류 발생&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cL0cl5/btrspKQo1Ma/L0p8zrF5c21zDrYlyoBQW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcL0cl5%2FbtrspKQo1Ma%2FL0p8zrF5c21zDrYlyoBQW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;183&quot; data-filename=&quot;Screen Shot 2022-02-03 at 7.24.46 PM.png&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오류 발생&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;package.json&lt;/code&gt; 파일에 가서 &lt;code&gt;&quot;type&quot;:&quot;module&quot;&lt;/code&gt;을 추가해줍니다, 이는 &lt;code&gt;script&lt;/code&gt; 방식으로 불러오는 것으로 기본값이 set되어 있어서, module 방식으로 바꿔준 것 입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;package.json 파일&lt;/h3&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;node&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;amp;&amp;amp; exit 1&quot;
  },
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;dependencies&quot;: {
    &quot;web3&quot;: &quot;^1.7.0&quot;
  },
  &quot;type&quot;: &quot;module&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 import 방식을 script로 진행했기 때문에 발생한 오류&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 실행해보니, 잘 해결되었습니다!&lt;/p&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>import</category>
      <category>json</category>
      <category>SyntaxError</category>
      <category>오류</category>
      <category>외부라이브러ㅣ</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/36</guid>
      <comments>https://wooong-dev.tistory.com/entry/SyntaxError-Cannot-use-import-statement-outside-a-module-%ED%95%B4%EA%B2%B0#entry36comment</comments>
      <pubDate>Thu, 3 Feb 2022 19:30:58 +0900</pubDate>
    </item>
    <item>
      <title>file is a commonjs module it may be converted to an es6 module 해결</title>
      <link>https://wooong-dev.tistory.com/entry/file-is-a-commonjs-module-it-may-be-converted-to-an-es6-module</link>
      <description>&lt;h1&gt;file is a commonjs module it may be converted to an es6 module&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트를 쓰다가 이런 경고를 봤을 것이다, 보통 자바스크립트에서 &lt;code&gt;require&lt;/code&gt;나 &lt;code&gt;import&lt;/code&gt;의 키워드를 통해서 외부 라이브러리를 불러오게됩니다. 이때&amp;nbsp;&lt;code&gt;require&lt;/code&gt;을 쓰면, 이러한 문구를 보게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-02-03 at 7.32.23 PM.png&quot; data-origin-width=&quot;881&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chIhxi/btrskugxVvm/lZdRKH9u8WFN83BlgrM02K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chIhxi/btrskugxVvm/lZdRKH9u8WFN83BlgrM02K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chIhxi/btrskugxVvm/lZdRKH9u8WFN83BlgrM02K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchIhxi%2FbtrskugxVvm%2FlZdRKH9u8WFN83BlgrM02K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;881&quot; height=&quot;67&quot; data-filename=&quot;Screen Shot 2022-02-03 at 7.32.23 PM.png&quot; data-origin-width=&quot;881&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알림 문구를 없애고 싶다면 두가지, 총 2가지 방법이 존재합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;settings.json&lt;/code&gt;파일에 설정값을 변경&lt;/li&gt;
&lt;li&gt;&lt;code&gt;import&lt;/code&gt;로 대체하는 방법&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. settings.json&lt;/h2&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;&quot;typescript.suggestionActions.enabled&quot;: false
&quot;javascript.suggestionActions.enabled&quot;: false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안을 보지 않게 합니다, 하지만 이는 이 알림 문구 이외에 &lt;b&gt;다른 문구들의 제안을 보지 못하기 때문에&lt;/b&gt;, 유의해야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. import&lt;/h2&gt;
&lt;pre class=&quot;capnproto&quot;&gt;&lt;code&gt;
import Web from &quot;web3&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import로 대체 시, &lt;code&gt;Cannot use import statement outside a module&lt;/code&gt;이라는 &lt;code&gt;SyntaxError&lt;/code&gt;가 나올 수 있습니다.&lt;br /&gt;해당 파일에서는 &lt;code&gt;package.json&lt;/code&gt; 파일에 &lt;code&gt;&quot;type&quot;: &quot;module&quot;&lt;/code&gt;의 문구를 추가해주면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;node&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;amp;&amp;amp; exit 1&quot;
  },
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;dependencies&quot;: {
    &quot;web3&quot;: &quot;^1.7.0&quot;
  },
  &quot;type&quot;: &quot;module&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게하면 정상적으로 &lt;code&gt;import&lt;/code&gt;와 경고문구를 해결하여 사용할 수 있습니다.&lt;/p&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>JavaScript</category>
      <category>경고</category>
      <category>문구해결</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/35</guid>
      <comments>https://wooong-dev.tistory.com/entry/file-is-a-commonjs-module-it-may-be-converted-to-an-es6-module#entry35comment</comments>
      <pubDate>Thu, 3 Feb 2022 19:21:19 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode, Longest Substring Without Repeating Characters (Golang)</title>
      <link>https://wooong-dev.tistory.com/entry/LeetCode-Longest-Substring-Without-Repeating-Characters-Golang</link>
      <description>&lt;h1&gt;Longest Substring Without Repeating Characters&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;첫번째 풀이 O(n2)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;처음 접근&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 접근법은 abcabcbb, &lt;code&gt;이중 반복문&lt;/code&gt;을 통해서 첫번째 문자열과 일치하는지를 확인하고, 일치하면, 거기서 &lt;code&gt;break&lt;/code&gt;를 걸어서 문자열 대치를 진행했다. &lt;b&gt;문제점&lt;/b&gt;은 첫번째 문자열만 일치한다는 점이였고, 2, 3 ... 이어지는 문자열이 존재하는지는 확인하지 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-27 at 8.24.47 PM.png&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDYgl9/btrrVn87rAA/aN12Wu5qFcxTXloF5wL7L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDYgl9/btrrVn87rAA/aN12Wu5qFcxTXloF5wL7L1/img.png&quot; data-alt=&quot;확인 불가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDYgl9/btrrVn87rAA/aN12Wu5qFcxTXloF5wL7L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDYgl9%2FbtrrVn87rAA%2FaN12Wu5qFcxTXloF5wL7L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1130&quot; height=&quot;252&quot; data-filename=&quot;Screen Shot 2022-01-27 at 8.24.47 PM.png&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;확인 불가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;따라서 수정한 접근, Hash Map을 활용한 Brute Force - O(n2)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &lt;code&gt;HashMap&lt;/code&gt;을 따로 생성하여, 반복적으로 확인하는 문자열마다 &lt;code&gt;HashMap&lt;/code&gt;에 존재여부를 판단하여, 진행한다.&lt;/p&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;    a := &quot;abcabcbb&quot;
    var ans, tmp int = 0, 0
    var hMap = make(map[rune]int)

    for j, i := range a {
        hMap[i] = 1
        tmp = 1

        for _, k := range a[j+1:] {
            _, exists := hMap[k]
            if !exists {
                tmp++
                hMap[k] = 1
            } else {
                break
            }
        }

        if ans &amp;lt; tmp {
            ans = tmp
        }
    }

    return ans&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Details&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Runtime: 334 ms, faster than 14.81% of Go online submissions for Longest Substring Without Repeating Characters.&lt;br /&gt;Memory Usage: 10.2 MB, less than 5.65% of Go online submissions for Longest Substring Without Repeating Characters.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;LeetCode 풀이법 투 포인터 이용 알고리즘 O(n)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;투포인터 알고리즘&lt;/code&gt;은 두 개의 포인터, 즉 left, right 나누어서 윈도우 내에 있는 데이터를 이용해서 left, right 포인터를 바꿔가며, 풀이하는 알고리즘을 말합니다. 이렇게 하면, 이중 반복문을 쓰지 않는 결과가 나옵니다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;
    a := &quot;abcabcbb&quot;

    var left, right, res int
    ch := make(map[byte]int)

    for right &amp;lt; len(a) {

        // 존재하는지 확인!
        index, exist := ch[a[right]]
        fmt.Println(index, exist)

        // 존재하면, 존재하는 index 인덱스에서 right 다시 증명 시작
        // left가 존재하는 다음 자리에서 다시 증명을 시작하는 이유는
        // 이미 right까지 중복한 숫자가 없다는 것을 증명했기 떄문
        if exist &amp;amp;&amp;amp; index &amp;gt;= left {
            left = index + 1
        }

        if res &amp;lt; right-left+1 {
            res = right - left + 1
        }

        ch[a[right]] = right

        right += 1
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투포인터를 이용해서, 알고리즘을 수정하면 O(n)이라는 결과값이 나옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Details&lt;/h4&gt;
&lt;div&gt;&lt;span&gt;Runtime:&amp;nbsp;&lt;span style=&quot;color: #263238;&quot;&gt;8 ms&lt;/span&gt;&lt;span&gt;, faster than&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #263238;&quot;&gt;74.88%&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;of&lt;span&gt;&amp;nbsp;&lt;/span&gt;Go&lt;span&gt;&amp;nbsp;&lt;/span&gt;online submissions for&lt;span&gt;&amp;nbsp;&lt;/span&gt;Longest Substring Without Repeating Characters.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Memory Usage:&amp;nbsp;&lt;span style=&quot;color: #263238;&quot;&gt;2.9 MB&lt;/span&gt;&lt;span&gt;, less than&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #263238;&quot;&gt;76.09%&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;of&lt;span&gt;&amp;nbsp;&lt;/span&gt;Go&lt;span&gt;&amp;nbsp;&lt;/span&gt;online submissions for&lt;span&gt;&amp;nbsp;&lt;/span&gt;Longest Substring Without Repeating Characters.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</description>
      <category>알고리즘/문제</category>
      <category>Golang</category>
      <category>leetcode</category>
      <category>개인 분석</category>
      <category>릿코드</category>
      <category>문제풀이</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/33</guid>
      <comments>https://wooong-dev.tistory.com/entry/LeetCode-Longest-Substring-Without-Repeating-Characters-Golang#entry33comment</comments>
      <pubDate>Thu, 27 Jan 2022 20:22:52 +0900</pubDate>
    </item>
    <item>
      <title>DID는 무엇일까?</title>
      <link>https://wooong-dev.tistory.com/entry/DID%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;DID(Decentralized Identify, 탈중앙 신원증명)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DID는 기존 신원 확인과는 달리 개인정보의 소유자인 사용자가 관리하고 통제(CRUD)를 할 수 있다는 특징을 갖습니다.&lt;br /&gt;&lt;code&gt;Decentralized(탈중앙 신원증명, 이하 DID)&lt;/code&gt;란?, 데이터의 주권이 개개인에게 있고, 필요할 때, 그 데이터를 중앙화 된 시스템을 거치지 않고 증명할 수 있는 기술로써, &lt;code&gt;분산 원장 기술(Distributed Ledger Technology)&lt;/code&gt;을 기반으로 사용자 저장하여 안전하고 편리한 인증 가능하도록 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SSI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;DID&lt;/code&gt;는 SSI를 위해서현실화하기 위해서 만들어진 개념입니다. &lt;code&gt;SSI&lt;/code&gt;는 스스로가 독립된 권한을 가진 신원, 자신이 스스로 부여한 신원을 말합니다. 신원의 소유권을 가진 주체가 신원에 대한 권리를 가지고 공개 대상과 범위를 선택할 수 있는 개념입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;신원관리 모델의 역사&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;1세대&lt;/code&gt;의 개별신원모델, &lt;code&gt;2세대&lt;/code&gt;의 연합형 신원 모델, &lt;code&gt;3세대&lt;/code&gt;의 자기 주권 신원 모델 순으로 발전해왔으며, 무조건 후세대에 나온 신버전 신원관리 모델을 채택하기보다는, 각자 기관의 이해관계에 따라서 채택하는 방식이 다릅니다. 각자 장단점이 있겠죠?&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;신원관리 SSI 모델의 종류&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;1세대 개별신원모델&lt;/code&gt;은 개별 서비스 제공자, 서비스 별로 회원가입 필요해 각각의 서비스마다 ID, Password 관리로 인해 불편하며,&lt;br /&gt;서비스 별로 보안 수준에 따라 신원정보 대량 유출이 가능하다는 단점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;2세대 연합형 신원&lt;/code&gt;은 중앙화 된 연결 서비스 제공자가 주체가 되어서 중앙화 된 연결 서비스를 통해서 회원가입을 하면, 연합형 신원을 제공하는 웹사이트는 모두 사용이 가능하다는 장점이 있으며, 하지만 이 중앙화된 연결 서비스가 얼마나 신뢰성을 가지지는 미지수이며, 하지만 웹사이트의 경우 관리가 편하다는 장점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;code&gt;3세대 자기 주권 신원&lt;/code&gt;은 주체는 개인정보 이용자 자신이며,&amp;nbsp; 즉, 개인의 개인정보를 자신 스스로 소유하게 되며, 발급 내역은 블록체인의 분산 원장에 저장되며, 개인의 신원을 증명할 신원정보를 받아서 검증자에게 신원정보를 공유할 수 있는 모델입니다. 이용자 편의성에서는 비밀번호를 잃어버릴 경우 다시 찾기가 어렵습니다. 그래서 각별한 관리가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SSI 3세대 구성요소&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-26 at 3.17.25 PM.png&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZE0br/btrrJlkc8ND/GqfGYAAy2uvcX1yANjKOLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZE0br/btrrJlkc8ND/GqfGYAAy2uvcX1yANjKOLk/img.png&quot; data-alt=&quot;SSI 구성요소&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZE0br/btrrJlkc8ND/GqfGYAAy2uvcX1yANjKOLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZE0br%2FbtrrJlkc8ND%2FGqfGYAAy2uvcX1yANjKOLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;408&quot; data-filename=&quot;Screen Shot 2022-01-26 at 3.17.25 PM.png&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSI 구성요소&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;SSI 구성요소&lt;/code&gt;는 발행자, 자격증명 소유자, 자격증명 검증자, 검증 데이터 저장소로 나뉘며, 각각 역할이 존재합니다.&lt;br /&gt;&lt;code&gt;발행자(Issuer)&lt;/code&gt;는 실원 정보를 발급하는 주체, &lt;code&gt;소유자(Holder)&lt;/code&gt;는 신원정보를 소유한 주체, &lt;code&gt;검증자(Verifier)&lt;/code&gt;는 신원정보를 검증하는 주체 역할을 합니다. 마지막으로 &lt;code&gt;저장소(Verifiable data Registry)&lt;/code&gt;는 정보주체의 식별자와 발급기관의 인증서, 신원증명 혜지내역, 신원증명 스키마 등이 등록되어 있는 분산 원장 기반의 데이터 무결성이 확보된 저장소를 말합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DID 표준&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;DID 표준 등장&lt;/code&gt;은 DIF(Decentralized Identify Foundation)의 주도로 개념과 설계가 세워졌으며 W3C를 통하여 국제 표준(Decentralized Identified Standard)이 제정되고 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DID 형식&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-26 at 3.23.00 PM.png&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7FRSM/btrrKIzjstY/hMqVGUvqxExv4mkmTrpJR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7FRSM/btrrKIzjstY/hMqVGUvqxExv4mkmTrpJR0/img.png&quot; data-alt=&quot;DID 형식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7FRSM/btrrKIzjstY/hMqVGUvqxExv4mkmTrpJR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7FRSM%2FbtrrKIzjstY%2FhMqVGUvqxExv4mkmTrpJR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;763&quot; height=&quot;270&quot; data-filename=&quot;Screen Shot 2022-01-26 at 3.23.00 PM.png&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DID 형식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;did&lt;/code&gt;는 문자열이 did임을 나타내며, 주소가 did 스키마에 따른 것임을 나타냅니다, &lt;code&gt;example&lt;/code&gt;은 did 메서드의 이름이고, did는 메서드 별로 다르게 처리됩니다, &lt;code&gt;123456789abcdefdefghi&lt;/code&gt;는 DID 메서드 안에서 사용되는 고유 아이디입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DID 비즈니스 모델 사용 사례&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대한민국에서는 코인플러그의 &lt;code&gt;마이키핀&lt;/code&gt;, SK텔레콤의 &lt;code&gt;이니셜&lt;/code&gt;, 라온시큐어의 &lt;code&gt;옴니원&lt;/code&gt;, 아이콘푸프의 &lt;code&gt;마이아이디&lt;/code&gt; 등이 대표적&lt;br /&gt;입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSI의 핵심가치는 데이터의 주권이 기관, 기업에서 개인에게 이동하게 됩니다. 따라서, 개인에게 책임이 높아지고, 더욱 안전하게 보관할 수 있다는 장점이 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이키핀 앱 서비스를 이용한 무인 편의점 사용기 참고 영상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https://www.youtube.com/watch?v=KqvSLu_g7no&amp;amp;t=19s&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;</description>
      <category>etc/블록체인</category>
      <category>did</category>
      <category>핵심 가치</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/32</guid>
      <comments>https://wooong-dev.tistory.com/entry/DID%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C#entry32comment</comments>
      <pubDate>Wed, 26 Jan 2022 15:16:20 +0900</pubDate>
    </item>
    <item>
      <title>ERC-721, NFT 뜻과 함수에 대해서 알아보자</title>
      <link>https://wooong-dev.tistory.com/entry/ERC-721-NFT-%EB%9C%BB%EA%B3%BC-%ED%95%A8%EC%88%98%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
      <description>&lt;h1&gt;ERC-721 = NFT&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;721번째 토론인 &lt;code&gt;EIP-721 토론&lt;/code&gt;은 하나하나의 구분 가능한 토큰에 대한 토론이 이뤄졌습니다.&lt;br /&gt;동전이 100원이 두개가 모이면 200원이 되는 것이 아니라 동전 하나하나의 구분 가능한 특징을 넣어서 100원 두개가 모여도, 동전 100원 1, 100원 2로 구분하듯이요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ERC-20 토큰과 ERC-721의 차이점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ERC-20 토큰: 2017년 당시 가장 많이 쓰이고 있던 토큰&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ERC-20 토큰&lt;/code&gt;은 일반적으로 발행하고 있는 토큰 발행 기준입니다. 주로 화폐를 대체 가능한&lt;br /&gt;암호화폐(토큰)을 지원하고 있기 떄문입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대체 가능한이란?, 누군가가 가지고 있는 100원은 내가 가지고 있는 100원가 동일한 가치를&lt;br /&gt;가지고 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ERC-721 토큰&lt;/code&gt;은 대체 불가능한 토큰을 지원합니다. ERC-721에서 발행하는 토큰들은 하나하나,&lt;br /&gt;각자의 특징을 가지고 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ERC-721 함수의 기능&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ERC712&lt;/code&gt;을 사용해서, 각각의 고유한 속성을 넣을 수 있씁니다. 그래서, 다양한 컨탠츠를 만들&lt;br /&gt;수 있습니다. 각각의 ERC-721의 함수를 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서에 있는 &lt;a href=&quot;https://docs.openzeppelin.com/contracts/3.x/erc721&quot;&gt;게임 아이탬 속성&lt;/a&gt;을 확인해보세요!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ApprovalForAll(address owner, address operator, bool approved)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;컨트랙트 오너(Owner)&lt;/code&gt;가 오퍼레이터(operator)에게 모든 자산을 관리할 수 있는 권한을 부여하거나 없앨 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ownerOf(uint256 tokenId) -&amp;gt; address owner&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;tokenId&lt;/code&gt;가 존재해야하고, tokenId 에 해당하는 NFT 소유자를 알려줍니다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;function owner(uint256, tokenId) public view virtual override returns (address) {
    // 소유자 변수
    address owner = _owner[tokenId];

    // 오류처리, address가 없을 경우
    require(owner != address(0), &quot;ERC721: owner query for nonexistent token&quot;)

    // return owner;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;setApprovalForAll(arress operator, bool _approved)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;operator&lt;/code&gt;의 권한(모든 자산을 관리)을 부여 혹은 없앨 수 있는 함수입니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;
function setApprovalForAll(arress operator, bool _approved) public virtual override {
    _setApprovalForAll(_msgSender(), operator, approved)
}

function _setApprovalForAll( address owner, address operator, bool approve) internal virtual {
        // 오류 확인
        require(owner != operator, &quot;ERC721: approve to caller&quot;);

        // 승인 후, 이밴트 발생
        _operatorApproval[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approve);
    }
)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;getApproved(uint256 tokenId) -&amp;gt; address operator&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;tokenId&lt;/code&gt;를 매개변수로 받으며, 승인된 계정의 주소를 다시 돌려줍니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;function getApproved(uint256 tokenId) public view virtual override returns (address) {
    // 에러 처리, tokenId가 존재하는지
    require(_exists(tokenId), &quot;ERC721: approved query for nonexistent token&quot;)
    return _tokenApprovals[tokenId];
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;isApprovedForAll(address owner, address operator) -&amp;gt; bool&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;operator&lt;/code&gt;가 owner의 주소를 관리할 수 있는지 확인하여 bool 값을 돌려줍니다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
    return _operatorApproval[owner][operator];]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ERC-165&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ERC165&lt;/code&gt;는 ERC-721의 스마트컨트랙트가 생성될 때, 구현해야하는 인터페이스 검사 및 사용하는지 검사를 진행하는&lt;br /&gt;역할을 하게됩니다.&lt;/p&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    // ERC165는 supportsInterface의 return bool만 가지고 있습니다.
    // 아 함수의 매개변수로 ERC-721의 인터페이스 ID를 입력해야만, ERC-721
    // 스마트 컨트랙트가 정상적으로 동작합니다.
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERC-721에 대해서 알아보았습니다.&lt;/p&gt;</description>
      <category>etc/solidity</category>
      <category>ERC-721</category>
      <category>nft</category>
      <category>블록체인</category>
      <category>설명</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/31</guid>
      <comments>https://wooong-dev.tistory.com/entry/ERC-721-NFT-%EB%9C%BB%EA%B3%BC-%ED%95%A8%EC%88%98%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90#entry31comment</comments>
      <pubDate>Fri, 21 Jan 2022 19:04:37 +0900</pubDate>
    </item>
    <item>
      <title>solidity - 테스트넷 simple token 배포하기 - 2 / 2 편</title>
      <link>https://wooong-dev.tistory.com/entry/solidity-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%84%B7-simple-token-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-2-2-%ED%8E%B8</link>
      <description>&lt;h1&gt;solidity - 테스트넷 simple token 배포하기 - 2 / 2 편&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번편에는 필요한 준비물이 두개 있습니다. 하나는 메타스크지갑(ropsten)이고,&lt;br /&gt;둘은 remix 연동입니다. 만약 준비물이 이미 준비가 되어있다면 배포하기로 넘어가서&lt;br /&gt;진행하시면 될 것 같습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#%EB%A9%94%ED%83%80%EB%A7%88%EC%8A%A4%ED%81%AC&quot;&gt;준비물&lt;/a&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메타마스크 설치&lt;/li&gt;
&lt;li&gt;메타마스크 테스트 지갑 열기&lt;/li&gt;
&lt;li&gt;remix와 메타마스크 연동&lt;/li&gt;
&lt;li&gt;Ropsten 테스트넷 이더리움 받기!&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0&quot;&gt;배포하기&lt;/a&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소스코드 컴파일 및 배포&lt;/li&gt;
&lt;li&gt;정상작동 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;준비물&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[1]메타마스크 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=ko&quot;&gt;메타마스크&lt;/a&gt;에 접속해 크롬에 추가 버튼을 누릅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.04.38 PM.png&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/II8jt/btrrcNIStvF/WuluQPpQFUptFyu0yBRoK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/II8jt/btrrcNIStvF/WuluQPpQFUptFyu0yBRoK0/img.png&quot; data-alt=&quot;메타마스크 설치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/II8jt/btrrcNIStvF/WuluQPpQFUptFyu0yBRoK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FII8jt%2FbtrrcNIStvF%2FWuluQPpQFUptFyu0yBRoK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1030&quot; height=&quot;238&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.04.38 PM.png&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메타마스크 설치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[2]메타마스크 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.초기 시작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;크롬 extension&lt;/code&gt;에 보면 메타마스크 아이콘이 나옵니다. 따라서, 이것을 클릭하면 웹페이지가 열리며, 시작하기 버튼이 있습니다. 여기서 지갑이 없는 경우 지갑 생성하시고, &lt;code&gt;비밀키&lt;/code&gt;가 있는 경우는 지갑 가져오기 누르시면 됩니다. 저는 지갑 생성을 누르겠습니다. 또한, 저는 메타마스크 개선에 참여하지 않겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.16.56 PM.png&quot; data-origin-width=&quot;1501&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cboRFF/btrrcPfDm4z/MQIzdKDYv7ks0HdRBxIHUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cboRFF/btrrcPfDm4z/MQIzdKDYv7ks0HdRBxIHUk/img.png&quot; data-alt=&quot;첫 시작&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cboRFF/btrrcPfDm4z/MQIzdKDYv7ks0HdRBxIHUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcboRFF%2FbtrrcPfDm4z%2FMQIzdKDYv7ks0HdRBxIHUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1501&quot; height=&quot;586&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.16.56 PM.png&quot; data-origin-width=&quot;1501&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;첫 시작&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.암호 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;암호 생성&lt;/code&gt;은 원하는 암호를 넣고 이용약관 확인 후에 생성 버튼을 누르시면 됩니다. 버튼을 누르면 나오는 &lt;code&gt;지갑 보호&lt;/code&gt; 영상을 보고, 지갑 보안 사항에 유의해주세요. 그리고나서, 다음 버튼을 눌러주시면 됩니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.20.32 PM 1.png&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mgOzv/btrricNWRPf/oQRcqH8pZA9rZm9E7b8aU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mgOzv/btrricNWRPf/oQRcqH8pZA9rZm9E7b8aU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mgOzv/btrricNWRPf/oQRcqH8pZA9rZm9E7b8aU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmgOzv%2FbtrricNWRPf%2FoQRcqH8pZA9rZm9E7b8aU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1384&quot; height=&quot;678&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.20.32 PM 1.png&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.Secret 복구 구문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Secret Recovery Pharase&lt;/code&gt;는 지갑을 다시 복구하기 위한 키며, 누구에게도 공개하면 안되는 키입니다. 따라서 암호화된 외장 드라이브나 숨겨진 곳에 잘 보관해야합니다. 그리고, 다음에 나오는 구문에 잘 맞춰서 잘 넣어서 해결해주세요, 이 지갑 복구 키는 꼭 잘 챙겨야 합니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.24.04 PM.png&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jq9uC/btrrd597JgO/wrhdcLK1hieepXrlkCFPIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jq9uC/btrrd597JgO/wrhdcLK1hieepXrlkCFPIK/img.png&quot; data-alt=&quot;복구키 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jq9uC/btrrd597JgO/wrhdcLK1hieepXrlkCFPIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJq9uC%2Fbtrrd597JgO%2FwrhdcLK1hieepXrlkCFPIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1405&quot; height=&quot;610&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.24.04 PM.png&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;복구키 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.테스트넷 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;메인넷&lt;/code&gt;에서 토큰을 발행하려면 가스비가 들어가기 때문에 테스트 용도로 쓰려면, &lt;code&gt;테스트넷&lt;/code&gt;에서 테스트를 진행하는 것이 좋습니다. 따라서 실습은 테스트넷에서 진행하므로, 테스트넷을 설정하도록 합니다. &lt;b&gt;클릭을 하면 설정창&lt;/b&gt;이 나옵니다. 여기서, &lt;b&gt;고급탭에&lt;/b&gt; 들어가서 show &lt;b&gt;test networks&lt;/b&gt;을 활성화하고, Ropsten 테스트 네트워크로 수정해줍니다. 그렇게하면 지갑설정은 완료되었습니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.27.09 PM.png&quot; data-origin-width=&quot;1454&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEiSop/btrrd71bI0x/SRZnYbppU2osiFkxQAnQvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEiSop/btrrd71bI0x/SRZnYbppU2osiFkxQAnQvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEiSop/btrrd71bI0x/SRZnYbppU2osiFkxQAnQvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEiSop%2Fbtrrd71bI0x%2FSRZnYbppU2osiFkxQAnQvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1454&quot; height=&quot;760&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.27.09 PM.png&quot; data-origin-width=&quot;1454&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아!, 그리고 지속적으로 메타마스크를 쓸 예정이면 pin을 해두시는게 좋습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.28.06 PM.png&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;595&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JwLHi/btrriVyoJNr/9cxXYsTv3a0V9kaptXlTaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JwLHi/btrriVyoJNr/9cxXYsTv3a0V9kaptXlTaK/img.png&quot; data-alt=&quot;핀 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JwLHi/btrriVyoJNr/9cxXYsTv3a0V9kaptXlTaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJwLHi%2FbtrriVyoJNr%2F9cxXYsTv3a0V9kaptXlTaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;270&quot; height=&quot;434&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.28.06 PM.png&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;595&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;핀 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[3] REMIX 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리믹스는 브라우저에서 솔리디티 프로그래밍 언어로 스마트 계약 개발과 구측을 지원하는 통합 개발 환경 IDE입니다. 따라서, 작성한 코드를 스마트 계약으로 배포와 테스트를 진행할 수 있습니다. 따라서 &lt;a href=&quot;https://remix.ethereum.org/&quot;&gt;https://remix.ethereum.org/&lt;/a&gt; 이곳에 접속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. REMIX 작성파일 올리기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/woong-s/blog/commit/523c4fe34e0773793dcf149002cf252630b7416c&quot;&gt;1편에서 작성한 소스코드&lt;/a&gt;에 복사하여 contract 폴더안에 파일을 만들어서 작성한 코드를 붙여넣도록 하겠습니다. 먼저, contract 폴더를 누르고, 우클릭, 파일을 생성하고, 생성한 파일에 코드를 붙여넣습니다. 저는 파일의 이름은 4.SimpleToken.sol이라고 지었습니다. 확장자명은 꼭 .sol로 통일해주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 9.27.07 PM.png&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;1167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q3GhK/btrricf9nIv/8kLH2fKZ7kRb8oWgZyLdmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q3GhK/btrricf9nIv/8kLH2fKZ7kRb8oWgZyLdmk/img.png&quot; data-alt=&quot;파일 올리기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q3GhK/btrricf9nIv/8kLH2fKZ7kRb8oWgZyLdmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq3GhK%2Fbtrricf9nIv%2F8kLH2fKZ7kRb8oWgZyLdmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;679&quot; data-filename=&quot;Screen Shot 2022-01-20 at 9.27.07 PM.png&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;1167&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파일 올리기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[4]Ropsten 테스트넷 이더리움 받기!&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 환경에서 진행할 때는 가스비가 필요합니다. 따라서, 테스트넷 이더리움을 받기위해서는 다양한 방법이 가능합니다. &lt;a title=&quot;faucet_ropsten&quot; href=&quot;https://faucet.ropsten.be/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;테스트 이더 사이트&lt;/a&gt;에 접속해서, 개인 주소를 복사후에 칸에 기입해서 테스트 이더를 받겠습니다, 버튼 클릭후, 시간이 좀 지난후에 지갑에 이더리움 테스트넷 코인이 들어옵니다, 너무 느리다면, &lt;a href=&quot;https://faucet.egorfine.com/&quot;&gt;https://faucet.egorfine.com/&lt;/a&gt; 여기서 받아도 됩니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 10.16.41 PM.png&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;595&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqmAyD/btrrjBGspW0/PJKqLRdghkV5gfOYTPnuQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqmAyD/btrrjBGspW0/PJKqLRdghkV5gfOYTPnuQk/img.png&quot; data-alt=&quot;테스트넷 이더리움 받기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqmAyD/btrrjBGspW0/PJKqLRdghkV5gfOYTPnuQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqmAyD%2FbtrrjBGspW0%2FPJKqLRdghkV5gfOYTPnuQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;445&quot; data-filename=&quot;Screen Shot 2022-01-20 at 10.16.41 PM.png&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;595&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트넷 이더리움 받기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배포하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 지갑, 파일, 이더리움 가스비까지 모든 준비를 마쳤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성한 것을 컴파일하여 배포하고, 정삭작동하는지 확인하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[1].컴파일 및 배포&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;컴파일&lt;/code&gt;을 하기 위해서는 컴파일 탭에 들어가서, 컴파일러 버전과, 언어, evm 버전을 확인하고, complile을 눌러줍니다.&amp;nbsp;&lt;br /&gt;&lt;code&gt;컴파일&lt;/code&gt;을 해서 컴퓨터가 이해하기 쉽게 만드는 과정이라고 생각하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 9.51.05 PM.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;946&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MFGaj/btrrdbJkcC9/8yqLq3HEW44s5AkFbyjuXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MFGaj/btrrdbJkcC9/8yqLq3HEW44s5AkFbyjuXK/img.png&quot; data-alt=&quot;컴파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MFGaj/btrrdbJkcC9/8yqLq3HEW44s5AkFbyjuXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMFGaj%2FbtrrdbJkcC9%2F8yqLq3HEW44s5AkFbyjuXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;564&quot; data-filename=&quot;Screen Shot 2022-01-20 at 9.51.05 PM.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;946&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 배포를 위한 모든 준비가 완료되었습니다. 배포를 진행해보겠습니다,&amp;nbsp; &amp;nbsp;배포탭에가서, injected Web3, Ropsten 테스트 넷 지갑주소, 그리고 컴파일한 계약 이름 SimpleToken과 마지막으로 발행할 토큰 이름과, 심볼이름을 정해줍니다. 저는 둘다 ALGO로 진행했습니다.&amp;nbsp;그리고&amp;nbsp;배포를&amp;nbsp;눌러주도록&amp;nbsp;합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 10.36.58 PM.png&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;1177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7G6Hy/btrrhTnBsZM/yU0gPMPOYaTggMouyi4nk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7G6Hy/btrrhTnBsZM/yU0gPMPOYaTggMouyi4nk1/img.png&quot; data-alt=&quot;배포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7G6Hy/btrrhTnBsZM/yU0gPMPOYaTggMouyi4nk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7G6Hy%2FbtrrhTnBsZM%2FyU0gPMPOYaTggMouyi4nk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;720&quot; data-filename=&quot;Screen Shot 2022-01-20 at 10.36.58 PM.png&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;1177&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배포&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[2].정상 작동확인&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;배포를 완료했습니다. 이제 토큰이 정상적으로 발행되었고, 송금이 되는지 확인해보겠습니다. 그럴려면, 내 지갑에&lt;br /&gt;발행한 토큰을 import 시켜줘야하고, 상대방 지갑도 필요합니다. 과정을 진행해보겠습니다. 발행한 스마트 계약&amp;nbsp; 토큰을 import 시켜주기 위해서는 계약 주소를 알아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #c8c3bc;&quot; data-darkreader-inline-color=&quot;&quot;&gt;transection hash값을 복사을 복사하고, &amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://ropsten.etherscan.io/&quot;&gt;&lt;span&gt;ether scan&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span&gt;사이트로 이동해서, 값을 붙여넣고 계약주소를 알아냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.41.44 PM.png&quot; data-origin-width=&quot;2122&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l4CNB/btrriVd6lDl/0pvy95XaQyzwSwlLGm6L21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l4CNB/btrriVd6lDl/0pvy95XaQyzwSwlLGm6L21/img.png&quot; data-alt=&quot;복사 후,&amp;amp;amp;amp;amp;nbsp; 이더 스캔 사이트에서 계약 주소를 알아냄&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l4CNB/btrriVd6lDl/0pvy95XaQyzwSwlLGm6L21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl4CNB%2FbtrriVd6lDl%2F0pvy95XaQyzwSwlLGm6L21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;917&quot; height=&quot;417&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.41.44 PM.png&quot; data-origin-width=&quot;2122&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;복사 후,&amp;amp;amp;amp;nbsp; 이더 스캔 사이트에서 계약 주소를 알아냄&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;import token 버튼을 누르고, &lt;/span&gt;&lt;span&gt;계약 주소를 넣고,&amp;nbsp; 정상적으로 계약 토큰이 들어왔는지 확인합니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.48.38 PM.png&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1bejp/btrribBxRpB/EqKRJxKSP2KUo8iuPZdoNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1bejp/btrribBxRpB/EqKRJxKSP2KUo8iuPZdoNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1bejp/btrribBxRpB/EqKRJxKSP2KUo8iuPZdoNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1bejp%2FbtrribBxRpB%2FEqKRJxKSP2KUo8iuPZdoNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1271&quot; height=&quot;796&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.48.38 PM.png&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;새로운 계정을 만들어줍니다, 그리고 새로운 계정에도 똑같이,&lt;b&gt; import token을&lt;/b&gt; 해줍니다. 이더스캔에서 가져왔었던, &lt;b&gt;계약 주소&lt;/b&gt;를 넣어주고&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt; &lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;b&gt;확인 버튼&lt;/b&gt;을 누릅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.57.35 PM.png&quot; data-origin-width=&quot;1115&quot; data-origin-height=&quot;615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ecZrVZ/btrrjBmakj9/JK2hTgKkVJsO1qbRmdCuSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ecZrVZ/btrrjBmakj9/JK2hTgKkVJsO1qbRmdCuSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ecZrVZ/btrrjBmakj9/JK2hTgKkVJsO1qbRmdCuSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FecZrVZ%2FbtrrjBmakj9%2FJK2hTgKkVJsO1qbRmdCuSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1115&quot; height=&quot;615&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.57.35 PM.png&quot; data-origin-width=&quot;1115&quot; data-origin-height=&quot;615&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 다시 account1 계정으로 돌아가서, account2 계정으로 생성한 토큰 ALGO를 10개 보내주도록하겠습니다. , account2의 주소는&amp;nbsp; 아까 클립보드에 복사했던 것으로 보내주면 됩니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.52.09 PM.png&quot; data-origin-width=&quot;1124&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6KCfr/btrrjBfotBr/YuFdHUd5fEwk3aUw4BszX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6KCfr/btrrjBfotBr/YuFdHUd5fEwk3aUw4BszX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6KCfr/btrrjBfotBr/YuFdHUd5fEwk3aUw4BszX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6KCfr%2FbtrrjBfotBr%2FYuFdHUd5fEwk3aUw4BszX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1124&quot; height=&quot;613&quot; data-filename=&quot;Screen Shot 2022-01-20 at 11.52.09 PM.png&quot; data-origin-width=&quot;1124&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;account2로 가니, ALGO 10개가 들어온 것을 보니 가시적으로 스마트 컨트랙트가 배포되었음을 확인할 수 있었습니다.&lt;/span&gt;&lt;span style=&quot;color: #c8c3bc;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-20 at 10.58.03 PM.png&quot; data-origin-width=&quot;356&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b325y3/btrrcOHNThi/NH5ucGfU7gvykGXjAA9k2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b325y3/btrrcOHNThi/NH5ucGfU7gvykGXjAA9k2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b325y3/btrrcOHNThi/NH5ucGfU7gvykGXjAA9k2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb325y3%2FbtrrcOHNThi%2FNH5ucGfU7gvykGXjAA9k2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;356&quot; height=&quot;594&quot; data-filename=&quot;Screen Shot 2022-01-20 at 10.58.03 PM.png&quot; data-origin-width=&quot;356&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제, 스마트 컨트랙트를 배포완료 했지만, 여전히 보완해야할 점이 있습니다. 그렇기 때문에 여러 문서를 보면서 수정하실 것을 추천드립니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천 문서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- erc-20 표준 문서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ethereum.org/ko/developers/docs/standards/tokens/erc-20/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ethereum.org/ko/developers/docs/standards/tokens/erc-20/&lt;/a&gt;&lt;/p&gt;</description>
      <category>etc/solidity</category>
      <category>ropsten</category>
      <category>Solidity</category>
      <category>스마트컨트랙트</category>
      <category>스마트컨트랙트배포</category>
      <category>테스트넷</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/30</guid>
      <comments>https://wooong-dev.tistory.com/entry/solidity-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%84%B7-simple-token-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-2-2-%ED%8E%B8#entry30comment</comments>
      <pubDate>Thu, 20 Jan 2022 23:00:31 +0900</pubDate>
    </item>
    <item>
      <title>solidity - 테스트넷 simple token 배포하기 - 1 / 2 편</title>
      <link>https://wooong-dev.tistory.com/entry/solidity-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%84%B7-simple-token-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-1-2-%ED%8E%B8</link>
      <description>&lt;h1&gt;ERC-20 이론부터 배포까지&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ERC-20&lt;/code&gt;(Ethereum Request for Comment 20), 20은 리퀘스트 숫자입니다. 이더리움 네트워크의 개선안을 제안하는&lt;br /&gt;&lt;code&gt;EIPs(Ethereum Improvement Proposals)&lt;/code&gt;에서 관리하는 공식 프로토콜입니다, ERC-20 은 비교적 간단한 이더리움 기반 토큰을 만들기 위한 규약을 의미합니다. &lt;code&gt;ERC-20&lt;/code&gt;을 사용하는 이유는 여러 종류의 토큰끼리 호환하기 위해서입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;즉, application와 contract가 상호작용하는 규약을 만드는 것을 목표로 합니다.&lt;br /&gt;이더리움 블록체인을 기반으로 다양한 탈중화한 애플리케이션들이 작동할 수 있도록 고안된 하나의 플랫폼이며,&lt;br /&gt;dApp들은 이러한 플랫폼에서 스마트 계약을 이용하여, 토큰을 발행할 수 있습니다. 또한 토큰은 계정 지갑에 존재하지 않으며, contract 내부에만 존재합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ERC-20 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;ERC-20의 생성&lt;/code&gt;, ERC-20 토큰을 생성하려면, &lt;code&gt;solidity&lt;/code&gt;라는 문법을 알아야 하고, ERC-20 규약을 지켜서 배포해야 합니다.&lt;br /&gt;ERC-20의 규약은 &lt;code&gt;전체 공급량(totalSupply)&lt;/code&gt;, &lt;code&gt;잔고(balanceOf)&lt;/code&gt;, &lt;code&gt;전송(transferFrom)&lt;/code&gt;, &lt;code&gt;승인(approve)&lt;/code&gt;, &lt;code&gt;허용(allowance)&lt;/code&gt;&lt;br /&gt;과 같이 포함되어야 합니다.&lt;/p&gt;
&lt;pre class=&quot;scilab&quot;&gt;&lt;code&gt;
// totalSupply, 콘트랙트가 보유하고 있는 토큰의 전체 공급량을 전달
function totalSupply() public view returns (uint256)

// balanceOf, 함수가 호출이 되면, 매개변수로 받았던 주소의 잔고를 공개합니다.
function balanceOf(address _owner) public view returns (uint256 balance)

// transfer,  다른 사용자에게 전송하는 것
function transfer(address _to, uint256 _value) public returns (bool success)

// tranferForm, franfer와 차이점을 요구하는데,
// 차이점은 다른 누군가 또는 다른 콘트랙트에서 여러분을 대신하여 자금을 
// 전송하도록 허락할 수 있습니다.
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)

// approve, 스마트 콘트랙트가 잔고에서 인출할 수 있는 토큰 수량을 제한할 수 있습니다.
function address(address _spender, uint256 _value) public returns (bool success)

//  allowance, approve와 함께 사용할 수 있으며, allowance는 토큰을 인출할 수 있는 
// 갯 수를 확인할 수 있습니다.
function allowance(address _owner, address _spender) public view return (uint256 remaining)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Simple Token 해석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 예제를 통해서 한번 Simple Token을 만들어보도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.10;

// solidity interface는 사용할 함수의 형태를 의미한다.
interface ERC20Interface {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function transferFrom(address spender, address recipient, uint256 amount) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Transfer(address indexed spender, address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 oldAmount, uint256 amount);
}

// simpleToken에서 ERC20Interface 함수를 선언하고, 함수 내용은 simpleToken에서 작성
contract SimpleToken is ERC20Interface {

    // mapping은 키와 값이 쌍으로 이루어진 해시 테이블
    mapping (address =&amp;gt; uint256) private _balances;
    mapping (address =&amp;gt; mapping (address =&amp;gt; uint256)) public _allowances;

    // 변수 선언 - 타입 권한 변수명 
    uint256 public _totalSupply;
    string public _name;
    string public _symbol;
    uint8 public _decimals;

    // constructor는 계약서가 배포될 때 호출
    // 계약서마다 1개만 생성가능
    constructor(string memory getName, string memory getSymbol) {
        _name = getName;
        _symbol = getSymbol;
        _decimals = 18;
        _totalSupply = 100000000e18;
        _balances[msg.sender] = _totalSupply;
    }

    /**
     * 토큰 이름을 반환합니다.
     */
    function name() public view returns (string memory) {
        return _name;
    }
    
    /**
     * symbol은 주로 이름을 줄여서 표현합니다. 
     * bitcoin을 btc로 부르른 것처럼 말이죠.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }
	
    /*
     *사용자 표현을 위한 소수 자릿수를 반환
     * decimals가 10, token이 100이면, 
     * (100 / 10 ** 10)과 같습니다.
     **/
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    // 전채 발행량 return
    function totalSupply() external view virtual override returns (uint256) {
        return _totalSupply;
    }

    // 매개 변수로 받은 account 
    function balanceOf(address account) external view virtual override returns (uint256) {
        return _balances[account];
    }

    // 내부 함수 _transfer를 먼저 사용하여, 유효성을 채킹을 합니다.
    // 1. 유효한 주소인지
    // 2. 요청한 수량이상 있는지
    // 그리고 정상적으로 해결되면
    // emit으로 Transfer event 실행
    // The Transfer Event 문서 (https://ethereumdev.io/transfers-and-approval-or-erc20-tokens-from-a-solidity-smart-contract/)
    function transfer(address recipient, uint amount) public virtual override returns (bool) {
        _transfer(msg.sender, recipient, amount);
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }

    // 토큰을 인출할 수 있는 갯수 확인
    // 내부함수 _approve를 통해서 확인후 승인
    function allowance(address owner, address spender) external view override returns (uint256) {
        return _allowances[owner][spender];
    }

    // 스마트 컨트랙트가 전송할 수 있는 토큰을 제한합니다.
    // 1. 유효한 주소인지 확인.
    // 2. emit
    function approve(address spender, uint amount) external virtual override returns (bool) {
        uint256 currentAllownace = _allowances[msg.sender][spender];
        require(currentAllownace &amp;gt;= amount, &quot;ERC20: Transfer amount exceeds allowance&quot;);
        _approve(msg.sender, spender, currentAllownace, amount);
        return true;
    }

    // 이하로는 내부함수를 작성한 내용입니다.
    // require은 오류를 체킹하여, 함수의 실행을 막는 역할을 합니다.
    // emit은 Event 실행을 의미합니다.

    function transferFrom(address sender, address recipient, uint256 amount) external virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        emit Transfer(msg.sender, sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][msg.sender];
        require(currentAllowance &amp;gt;= amount, &quot;ERC20: transfer amount exceeds allowance&quot;);
        _approve(sender, msg.sender, currentAllowance, currentAllowance - amount);
        return true;
    }

    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), &quot;ERC20: transfer from the zero address&quot;);
        require(recipient != address(0), &quot;ERC20: transfer to the zero address&quot;);
        uint256 senderBalance = _balances[sender];
        require(senderBalance &amp;gt;= amount, &quot;ERC20: transfer amount exceeds balance&quot;);
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;
    }

    function _approve(address owner, address spender, uint256 currentAmount, uint256 amount) internal virtual {
        require(owner != address(0), &quot;ERC20: approve from the zero address&quot;);
        require(spender != address(0), &quot;ERC20: approve to the zero address&quot;);
        require(currentAmount == _allowances[owner][spender], &quot;ERC20: invalid currentAmount&quot;);
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, currentAmount, amount);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 작성을 완료 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 편에는 직접적으로 배포하는 내용을 작성하겠습니다.&lt;/p&gt;</description>
      <category>etc/solidity</category>
      <category>Solidity</category>
      <category>블록체인</category>
      <category>스마트계약</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/29</guid>
      <comments>https://wooong-dev.tistory.com/entry/solidity-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%84%B7-simple-token-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-1-2-%ED%8E%B8#entry29comment</comments>
      <pubDate>Wed, 19 Jan 2022 18:59:28 +0900</pubDate>
    </item>
    <item>
      <title>golang - 테트리스 (1) 편</title>
      <link>https://wooong-dev.tistory.com/entry/golang-%ED%85%8C%ED%8A%B8%EB%A6%AC%EC%8A%A4-1-%ED%8E%B8</link>
      <description>&lt;h1&gt;Console Tetris 만들기 (1)&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이드 프로잭트로 console에 테트리스를 만드는 시간을 가지고 있습니다. 이 편은 3~5편 사이로 예상하고 있으며, 코드가 구현될 때마다 분류하여 정리해서 올려보도록 하겠습니다. 1편은 키보드 입력을 받는 부분을 만들어 보겠습니다. &lt;code&gt;console 라이브러리&lt;/code&gt;중에 콘솔에 색깔을 출력하고, 키보드 입력을 받는 &lt;code&gt;termbox-go&lt;/code&gt;를 통해서 만들어 보도록 하겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1편 요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 편에는 입력을 받고, 입력을 수행하는 스레드가 두개가 필요하여 시분할 처리를 수행하는 고루틴을 통해서 만들겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 입력을 받는 &lt;code&gt;go routine 1&lt;/code&gt;, 입력을 받아서 명령을 수행하는 &lt;code&gt;go routine 2&lt;/code&gt;, 를 만들어서 수행하도록&lt;br /&gt;할 것 입니다. 먼저 &lt;code&gt;go routine1&lt;/code&gt;을 만들것 입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;go routine1&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고루틴 시작전에 &lt;code&gt;sync&lt;/code&gt;로 go routine이 main 함수보다 늦게&lt;br /&gt;끝날 것을 고려해 설정해야하기 떄문에 &lt;code&gt;wait.Add(2)&lt;/code&gt;로&lt;br /&gt;메인 함수가 기달려달라고 설정해야합니다.&lt;/p&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;
// sync wait 버전을 만듭니다.
var wait sync.WaitGroup
wait.Add(2)


// termbox 초기 시작
err := termbox.Init()
if err != nil {
    panic(err)
}
defer termbox.Close()

// termbox event Queue, go routine1 생성
// 이벤트를 지속적으로 받아옵니다.
eventQueue := make(chan termbox.Event)
go func() {
    for {
        defer wait.Done()
        eventQueue &amp;lt;- termbox.PollEvent()
    }
}()&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;go routine2&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고루틴 2는 앞서 만든 eventQueue를 통해서, 받고 그 Type에 따라서 명령어 타임을 진행해주면 됩니다.&lt;br /&gt;그 과정에서 go-routine으로 받은 값이기 떄문에, select가 필요합니다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;// goroutine2 생성합니다.
go func() {
    for {
        // 채널을 통해서 받아오므로 select문 
        select {
        case qu := &amp;lt;- eventQueue:

            // Type에 따라서 분류하여 작동
            if qu.Type == termbox.EventKey {
                switch {
                case qu.Key == termbox.KeyArrowLeft:
                    fmt.Println(&quot;left&quot;)
                case qu.Key == termbox.KeyArrowRight:
                    fmt.Println(&quot;right&quot;)
                case qu.Key == termbox.KeyArrowUp:
                    fmt.Println(&quot;up&quot;)
                case qu.Key == termbox.ArrowDown:
                    fmt.Println(&quot;down&quot;)
                case qu.Key == termbox.KeySpace:
                    fmt.Println(&quot;space&quot;)
                case qu.Key == termbox.KeyEsc:
                    wait.Done()
                }
            }
        default:
            time.Sleep(tetrisSpeed)
        }
    }
}()
wait&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전체코드&lt;/h2&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package main

import (
    &quot;fmt&quot;
    &quot;sync&quot;
    &quot;time&quot;

    &quot;github.com/nsf/termbox-go&quot;
)

const tetirisSpeed = 10 * time.Millisecond

func main() {
    var wait sync.WaitGroup
    wait.Add(2)

    err := termbox.Init()
    if err != nil {
        panic(err)
    }
    defer termbox.Close()

    eventQueue := make(chan termbox.Event)
    go func() {
        for {
            eventQueue &amp;lt;- termbox.PollEvent()
        }
    }()

    go func() {
        for {
        	// go routine에 의해서, switch문을 select로 대체
            select {
           
            case qu := &amp;lt;-eventQueue:
            	// Type에 따라서 분류
                if qu.Type == termbox.EventKey {
                    switch {
                    case qu.Key == termbox.KeyArrowLeft:
                        fmt.Println(&quot;left&quot;)
                    case qu.Key == termbox.KeyArrowRight:
                        fmt.Println(&quot;right&quot;)
                    case qu.Key == termbox.KeyArrowUp:
                        fmt.Println(&quot;up&quot;)
                    case qu.Key == termbox.KeySpace:
                        fmt.Println(&quot;space&quot;)
                    case qu.Key == termbox.KeyArrowDown:
                        fmt.Println(&quot;down&quot;)
                    case qu.Key == termbox.KeyEsc:
                        fmt.Println(&quot;done&quot;)
                        wait.Done()
                        wait.Done()
                    }
                }
            default:
                time.Sleep(tetrisSpeed)
            }
        }
    }()
    // go routine 끝날 떄까지, 기다리기
    wait.Wait()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면, 종료키, 위, 아래, 스페이스, 오른쪽, 왼쪽 키가 정상적으로 입력되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tetrisSpeed는 블락이 떨어지는 속도를 의미합니다. 이것을 통해서 난이도를 변경하거나 할 수 있을 것 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;output.gif&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qtjhz/btrq4qUggmP/aTgCPHJS0CHyyH4aTrS7pk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qtjhz/btrq4qUggmP/aTgCPHJS0CHyyH4aTrS7pk/img.gif&quot; data-alt=&quot;입력 받기 성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qtjhz/btrq4qUggmP/aTgCPHJS0CHyyH4aTrS7pk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/qtjhz/btrq4qUggmP/aTgCPHJS0CHyyH4aTrS7pk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;202&quot; data-filename=&quot;output.gif&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;입력 받기 성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 편에는 golang 본판을 짜보는 시간을 가지겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- github code&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/woong-s/console_go_tetris/commit/4641bcb0a3ea21ab810970e428fb7131e55d2279&quot;&gt;https://github.com/woong-s/console_go_tetris/commit/4641bcb0a3ea21ab810970e428fb7131e55d2279&lt;/a&gt;&lt;/p&gt;</description>
      <category>언어/GO</category>
      <category>go</category>
      <category>Golang</category>
      <category>Tetrix</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/28</guid>
      <comments>https://wooong-dev.tistory.com/entry/golang-%ED%85%8C%ED%8A%B8%EB%A6%AC%EC%8A%A4-1-%ED%8E%B8#entry28comment</comments>
      <pubDate>Wed, 19 Jan 2022 01:40:27 +0900</pubDate>
    </item>
    <item>
      <title>ls 명령어 옵션  간단 정리</title>
      <link>https://wooong-dev.tistory.com/entry/ls-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%98%B5%EC%85%98-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC</link>
      <description>&lt;h1&gt;ls 명령어 간단정리&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ls 명령어는 폴더안의 내용을 리스트 출력하는데 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;# 리스트를 1라인으로 출력
ls -1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.34.13 PM.png&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s89D6/btrq8Jj5dxG/O9zSbcDlZh87SM0DcTUJ9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s89D6/btrq8Jj5dxG/O9zSbcDlZh87SM0DcTUJ9K/img.png&quot; data-alt=&quot;ls -1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s89D6/btrq8Jj5dxG/O9zSbcDlZh87SM0DcTUJ9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs89D6%2Fbtrq8Jj5dxG%2FO9zSbcDlZh87SM0DcTUJ9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;359&quot; height=&quot;180&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.34.13 PM.png&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ls -1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# 폴더안의 숨겨진 파일도 출력
ls -a&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.36.47 PM.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CRsYr/btrq6OTXLSx/yGz4BF4XOkUiYkNlcIIWj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CRsYr/btrq6OTXLSx/yGz4BF4XOkUiYkNlcIIWj1/img.png&quot; data-alt=&quot;ls -a&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CRsYr/btrq6OTXLSx/yGz4BF4XOkUiYkNlcIIWj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCRsYr%2Fbtrq6OTXLSx%2FyGz4BF4XOkUiYkNlcIIWj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;63&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.36.47 PM.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ls -a&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;# 폴더 이름 파일에 '/'을 붙여서 출력
ls -F&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.37.14 PM.png&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;51&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btWA9N/btrq4pVaQyX/wXUyTkuek8h90FTdM1gBKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btWA9N/btrq4pVaQyX/wXUyTkuek8h90FTdM1gBKK/img.png&quot; data-alt=&quot;ls -F&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btWA9N/btrq4pVaQyX/wXUyTkuek8h90FTdM1gBKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtWA9N%2Fbtrq4pVaQyX%2FwXUyTkuek8h90FTdM1gBKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;51&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.37.14 PM.png&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;51&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ls -F&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 리스트의 다양한 정보를 출력
# permissions, ownership, size, modification date
ls -la&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.37.33 PM.png&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHLX3Q/btrq8Jdk2Z4/oyl5259AH0oqYFYy9JVsu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHLX3Q/btrq8Jdk2Z4/oyl5259AH0oqYFYy9JVsu0/img.png&quot; data-alt=&quot;ls -la&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHLX3Q/btrq8Jdk2Z4/oyl5259AH0oqYFYy9JVsu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHLX3Q%2Fbtrq8Jdk2Z4%2Foyl5259AH0oqYFYy9JVsu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;531&quot; height=&quot;218&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.37.33 PM.png&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ls -la&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# 리스트의 사이즈를 정렬해서 출력
ls -lh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.37.58 PM.png&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SoIAh/btrq4p8LFeT/SNfd352pvk7oCC4hJ7Hyz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SoIAh/btrq4p8LFeT/SNfd352pvk7oCC4hJ7Hyz0/img.png&quot; data-alt=&quot;ls -lh&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SoIAh/btrq4p8LFeT/SNfd352pvk7oCC4hJ7Hyz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSoIAh%2Fbtrq4p8LFeT%2FSNfd352pvk7oCC4hJ7Hyz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;174&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.37.58 PM.png&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;174&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ls -lh&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# 수정된 날짜에 의해서 모든 파일 리스트를 정렬해서 출력
ls -ltr&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.38.23 PM.png&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSdHxI/btrq22zh2ma/TTYWfoWXMiI75tPa7AWRZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSdHxI/btrq22zh2ma/TTYWfoWXMiI75tPa7AWRZ1/img.png&quot; data-alt=&quot;ls -ltr&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSdHxI/btrq22zh2ma/TTYWfoWXMiI75tPa7AWRZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSdHxI%2Fbtrq22zh2ma%2FTTYWfoWXMiI75tPa7AWRZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;176&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.38.23 PM.png&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ls -ltr&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# 폴더만 출력
ls -d */&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.38.41 PM.png&quot; data-origin-width=&quot;242&quot; data-origin-height=&quot;51&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZpGUO/btrq6KD2Xeo/FCxR4AEva44KM84VlS5mLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZpGUO/btrq6KD2Xeo/FCxR4AEva44KM84VlS5mLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZpGUO/btrq6KD2Xeo/FCxR4AEva44KM84VlS5mLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZpGUO%2Fbtrq6KD2Xeo%2FFCxR4AEva44KM84VlS5mLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;242&quot; height=&quot;51&quot; data-filename=&quot;Screen Shot 2022-01-18 at 8.38.41 PM.png&quot; data-origin-width=&quot;242&quot; data-origin-height=&quot;51&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>etc/명령어 정리</category>
      <category>bash</category>
      <category>command</category>
      <category>linux</category>
      <category>LS</category>
      <category>간단</category>
      <category>리눅스</category>
      <category>명령어</category>
      <category>주요</category>
      <category>주요옵션</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/27</guid>
      <comments>https://wooong-dev.tistory.com/entry/ls-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%98%B5%EC%85%98-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC#entry27comment</comments>
      <pubDate>Tue, 18 Jan 2022 20:39:51 +0900</pubDate>
    </item>
    <item>
      <title>솔리디티(solidity) 문법 (간단 정리)</title>
      <link>https://wooong-dev.tistory.com/entry/%EC%86%94%EB%A6%AC%EB%94%94%ED%8B%B0solidity-%EB%AC%B8%EB%B2%95-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC</link>
      <description>&lt;h1&gt;solidity grammar&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;솔리디티&lt;/code&gt;는 EVM(Ethereum Vitual Machine) 에서 실행되는 스마트 컨트랙트 개발을 위해 설계된 정적 타입의 중괄호를 사용하는 프로그래밍 언어입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트컨트랙트란, 블록체인 기반으로 체결하는 계약을 말합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SPDX License Identifier&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저작권 문제, 스마트 컨트랙트 신뢰의 문제를 해소하기 위해서 SPDX License 문제를 해결&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Pragma&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pragma 키워드는 특정 컴파일러의 버전을 표기할 때 사용&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;
// 0.8.7 버전 사용
pragma solidity 0.8.7;

// 0.8.7 이상의 버전을 사용
pragma solidity ^0.8.7
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;import&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 임포트 하는 방식은 자바스크립트와 비슷하다.&lt;/p&gt;
&lt;pre class=&quot;xl&quot;&gt;&lt;code&gt;import &quot;file_path&quot;

// alias 설정
import &quot;file_path&quot; as symbolName;

// 파일의 일부만 import
import {symbol1 as alias symbol2} from &quot;file_path&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;컨트랙트 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트랙트에는 &lt;code&gt;변수(State Varliable)&lt;/code&gt;, &lt;code&gt;함수(Functions Modifiers)&lt;/code&gt;, &lt;code&gt;에러(Errors)&lt;/code&gt;, &lt;code&gt;상속(ingeritance)&lt;/code&gt;&lt;br /&gt;, &lt;code&gt;열거형(Enum Type)&lt;/code&gt; 등으로 구성합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상태 변수(State Valirable)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태 변수는 값이 컨트랙트 스토리지에 영구적으로 저장되는 변수&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;pragma solidity ^0.8.7;

contract SimpleStorage {
    uint storedData; // 상태 변수 선언
    uint storedData = 20; // 상태 변수와 초기값 선언
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;값형 데이터 타입&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값형 데이터 타입에는, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;byte1~byte32&lt;/code&gt;, &lt;code&gt;adress&lt;/code&gt;가 있습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;// bool
bool isOpen = true;
bool isSold = false;

// int, uint
int8 seoulTemp = -20
uint myAge = 30

// byte
byte3 alphabets = 'abc'
alphabets[0]
alphabets[1]
alphabets[2]

// adress

address MyAddress = 0x10abb5efEcdc01234f7b2384912398798E089Ab2;

// 스마트 컨트랙트에서 특정 주소값으로 송금을하기 위해선,
// **address payable** 형식을 사용

address addr1;
address payable p_addr1 = payable(addr1);&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;constan로 상수로 선언을 할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참조형 데이터 타입&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;참조형 변수(reference type)&lt;/code&gt;은 배열과 같이, 데이터를 저장하는 영역에 연속되어&lt;br /&gt;저장되어 있는 값의 첫번째 메모리의 주소를 값으로 가지는 변수 타입&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리란?&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 동작하는 동안에만 값을 기억, 종료되면 값을 잃는 데이터 영역&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스토리지?&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인에 기록되어 영구적으로 값이 유지되는 데이터영역&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function f() {
    // 5개의 int32 형태의 메모리를 저장하는 ixedSlots를 선언
    int32[5] memory fixedSlots;
    fixedSlots[0] = 13;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조형 변수의 유형&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열&lt;/li&gt;
&lt;li&gt;문자열&lt;/li&gt;
&lt;li&gt;구조체&lt;/li&gt;
&lt;li&gt;매핑&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// array
uint[] {array_name}
uint[4] {array_name}


// string
string name = 'kimcoding'


// struct
contract exampleC {
    struct UserInfo {
        address account
        string lastName;
        string firstName;
    }
    function createUser(address createAddress, string createLastName, string createFirstName) {
        UserInfo memory newUser = UserInfo({account: createUser, createLastName, firstName: createLastName})
    }
}

// mapping
// mapping은 스토리지 데이터 영역에 키-값 구조로 데이터를 저장할 떄 사용하는 참조형

mapping(address =&amp;gt; int) public userAdress&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;글로벌 변수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글로벌 변수는 solidity 언어에 내장되어 있는 변수&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;block&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;block&lt;/code&gt;는 블록에 대한 정보&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;msg&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;msg&lt;/code&gt;는 컨트랙트를 시작한 트랜잭션 콜이나 메시지 콜에 대한 정보&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;3&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;tx&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;tx&lt;/code&gt;는 트랜잭션 데이터&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;4&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;This&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;This&lt;/code&gt;는 현재 컨트랙트를 참조&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;함수&lt;/h2&gt;
&lt;pre class=&quot;nimrod&quot;&gt;&lt;code&gt;
function functionName(pram1, pram2, pram3) {...}

// 함수 변경자
// 함수 선언에 modifier를 추가하여 함수에 변경자를 적용할 수 있습니다.
// changeNum 변경자 시작 -&amp;gt; 본 함수 시작
int public num = 0;
modifier changeNum {
    num++;
    _;
    num--;
}

function func() public changeNum {
    if (num == 1){
        // do something
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상속&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔리디티의 &lt;code&gt;contract&lt;/code&gt; 객체는 상속을 지원합니다. 상속을 통해 컨트랙트에 기능들을 추가, 확장&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;
// 상속
contract ChildContract is Parentcontract {

}

// 다중 상속
contract ChildContract is Parentcontract1, Parentcontract2, Parentcontract3 {

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;에러 핸들링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔리디티에서는 에러를 처리할 때는 assert, require, revert 함수를 사용&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;revert&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 함수를 종료하고 에러를 리턴&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; start=&quot;2&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;require, assert&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정한 조건이 참인지 확인하고, 조건이 거짓이면 에러를 리턴&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;열거형&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;열거(enum)&lt;/code&gt;은 특정 값들로 집합을 지정하고, 집합에 있는 데이터만을 값으로 가집니다.&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;
enum EvelLevel {Bad, Soso, Great}

// 열거형 변수 선언
EvelLevel valName = EvelLevel.Bad

// 집합의 데이터 순서에 따라 0부터 1씩 증가
int16 valName = int16(kimcoding)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이벤트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트는 어떤 결과가 발생했을 때 해당 컨트랙트에서 dApp&lt;br /&gt;클라이언트, 또는 다른 컨트랙트에서 전달&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;contract coinTransfer {
// event eventName(param1Type pram1, param2Type pram2, uint256 value)
event Transfer(address from, address to, uint256)
function transfer(address to, address amount){
    // ...
    // emit eventName(pram1, pram2 ...)
    emit Transfer(msg.sender, to, amount)
}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>etc/solidity</category>
      <category>Solidity</category>
      <category>간단</category>
      <category>간단문법</category>
      <category>문법정리</category>
      <category>솔리디티</category>
      <category>언어</category>
      <category>프로그래밍</category>
      <category>프로그래밍언어</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/26</guid>
      <comments>https://wooong-dev.tistory.com/entry/%EC%86%94%EB%A6%AC%EB%94%94%ED%8B%B0solidity-%EB%AC%B8%EB%B2%95-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC#entry26comment</comments>
      <pubDate>Mon, 17 Jan 2022 17:55:48 +0900</pubDate>
    </item>
    <item>
      <title>ssh_config, sshd_config 파일의 차이점</title>
      <link>https://wooong-dev.tistory.com/entry/sshconfig-sshdconfig%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EB%B0%8F-sshdconfig-%EC%84%A4%EC%A0%95-1</link>
      <description>&lt;h1&gt;SSH&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;SSH&lt;/code&gt;는 Secure Shell Protoco의 약자입니다.&lt;br&gt;네트워크 상의 다른 컴퓨터에 로그인하여 원격 시스템에 명령을 실행하고, 파일을 가져오거나,&lt;br&gt;넣는 행위를 할 수 있습니다. 기존에 &lt;code&gt;telnet&lt;/code&gt;, &lt;code&gt;rsh&lt;/code&gt;, &lt;code&gt;rlogin&lt;/code&gt; 등의 인증 및 신뢰성을&lt;br&gt;보장하지 않는 프로토콜을 대체하여 쓰기 위해서 만들었습니다.&lt;/p&gt;
&lt;h2&gt;ssh_config와 sshd_config 파일의 차이점?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;linux&lt;/code&gt; 우분투 시스템에 &lt;code&gt;/etc/ssh&lt;/code&gt; 경로에 찾아서 들어가보면, &lt;code&gt;ssh_config&lt;/code&gt;와 &lt;code&gt;sshd_config&lt;/code&gt;의&lt;br&gt;설정 파일이 있는 것을 확인할 수 있는데, 이의 차이점&lt;/p&gt;
&lt;h3&gt;ssh_config&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ssh_config&lt;/code&gt;는 내부 서버에서 외부 서버에 원격으로 접속할 때, 설정하는 파일입니다&lt;/p&gt;
&lt;h3&gt;sshd_config&lt;/h3&gt;
&lt;p&gt;외부서버에서 내부 서버에 접속할 때, 설정하는 파일입니다.&lt;br&gt;&lt;code&gt;sshd_config&lt;/code&gt;는 다양한 설정을 할 수 있으며, root login 허락밑 특정 아이피 차단을 할 수 있으며, 그 외에 많은 설정을 다룰 수 있습니다.&lt;/p&gt;
&lt;hr&gt;</description>
      <category>etc/보안</category>
      <category>SSH</category>
      <category>sshd_config</category>
      <category>ssh_config</category>
      <category>보안</category>
      <category>차이점</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/25</guid>
      <comments>https://wooong-dev.tistory.com/entry/sshconfig-sshdconfig%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EB%B0%8F-sshdconfig-%EC%84%A4%EC%A0%95-1#entry25comment</comments>
      <pubDate>Mon, 17 Jan 2022 01:41:18 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode - Two Sum (Golang)</title>
      <link>https://wooong-dev.tistory.com/entry/LeetCode-Two-Sum-Golang</link>
      <description>&lt;h1&gt;LeetCode TwoSum&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예제&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;내가 푼 풀이&lt;/h2&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;func twoSum(nums []int, target int) []int {
    resultValue := make([]int, 2)

    for i := 0; i &amp;lt; len(nums); i++ {
        for j := 0; j &amp;lt; len(nums); j++ {
            if i == j {
                continue
            }
            if nums[i]+nums[j] == target {
                resultValue[0] = i
                resultValue[1] = j
                return resultValue
            }
        }
    }
    return resultValue
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;내가 생각한 방식 O(n2)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서는 반복문 두번을 통해서 촤익의 경우, &lt;code&gt;O(n2)&lt;/code&gt;의 무차별 대입 연산이 나오도록 설계했고,&lt;br /&gt;간단하게 생각해서 &lt;code&gt;i==j&lt;/code&gt;가 같은 경우에는 continue를 통해서 다음 연산으로 넘어가게 만들었다.&lt;br /&gt;그리고, &lt;code&gt;nums[i]&lt;/code&gt;와 &lt;code&gt;num[j]&lt;/code&gt;를 더한 값이 목표값과 같은 경우에는 resultValue에 자릿수를 기입을&lt;br /&gt;통해서, &lt;code&gt;return&lt;/code&gt;하게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해쉬 테이블 O(n)&lt;/h2&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;func twoSum(nums []int, target int) []int {
    var map1 = make(map[int]int)
    for idx, numi := range nums {
        num := target - numi
        if j, ok := map1[num]; ok {
            return []int{j, idx}
        }
        map1[numi] = idx
    }
    return []int{0, 0}
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;리뷰&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 활용을 잘하는 방법인 것 같습니다.&lt;br /&gt;이미 있는 데이터를 가지고 다음 반복문이 올 때, 지금의 데이터를&lt;br /&gt;활용할 수 있는 &lt;code&gt;방안(map)&lt;/code&gt;을 제공해주는 것 입니다.&lt;/p&gt;</description>
      <category>알고리즘/문제</category>
      <category>go</category>
      <category>Golang</category>
      <category>TwoSum</category>
      <category>알고리즘</category>
      <category>풀이</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/23</guid>
      <comments>https://wooong-dev.tistory.com/entry/LeetCode-Two-Sum-Golang#entry23comment</comments>
      <pubDate>Fri, 14 Jan 2022 22:09:34 +0900</pubDate>
    </item>
    <item>
      <title>[LInux] bash shell export (환경변수)</title>
      <link>https://wooong-dev.tistory.com/entry/LInux-bash-shell-export-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;환경변수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환경 변수 (environment variable)는 프로세스가 컴퓨터에서 동작하는데 미치는, 동적인 값들의 모임들을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제마다 설정하는 방법이 제각각 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;환경변수 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 환경변수를 설정하기 위해서 임시로 지정하는 방법&lt;/p&gt;
&lt;pre id=&quot;code_1642075005047&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export name=&amp;lt;지정_이름&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법의 경우에는 컴퓨터를 리부팅할 시에&amp;nbsp; 초기화되므로, 영구적으로 지정하는 방법이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 bash에서 작업을 진행할 때마다 수행되는 파일인 ~/.bashrc 파일을 열어 해당 내용을 넣어주도록 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 환경변수를 영구적으로 설정하기 위한 방법&lt;/p&gt;
&lt;pre id=&quot;code_1642075254486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# editor 열기
vi ~/.bashrc

# 환경변수 파일안에 기입
export name=&amp;lt;지정_이름&amp;gt;
# 저장하고 나오기
:wq 

# bashrc 파일 적용
source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 bash를 실행할 때마다 환경변수가 설정될 것 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;환경변수 설정확인&lt;/h2&gt;
&lt;pre id=&quot;code_1642075503987&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;echo $name&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면&amp;nbsp; 최종적으로 설정이 잘된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PATH&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔가다가 명령어를 설치했는데, 명령어가 실행되지 않는 경우가 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우에는 명령어 실행파일이 $PATH라는 환경변수에 적용이 안된 경우도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 경우, 실행 파일이 있는 경로를 찾아서 환경 변수 $PATH에 넣어 주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 PATH는 명령어 경로의 모임이라고 보면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1642075922951&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기존에 있는 명령어 경로와 새로운 명령어 경로를 더합니다.
export PATH=$PATH:&amp;lt;명령어_경로&amp;gt; # o

# 이렇게 하면 PATH에 명령어 경로 하나만 지정되어서
# ls, find, cd, 이런 명령어가 적용이 안되어, 기존에 있던 것을
# 다 추가해줘야 합니다.
export PATH=&amp;lt;명령어_경로&amp;gt; # x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>export</category>
      <category>path</category>
      <category>리눅스</category>
      <category>환경변수</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/22</guid>
      <comments>https://wooong-dev.tistory.com/entry/LInux-bash-shell-export-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98#entry22comment</comments>
      <pubDate>Thu, 13 Jan 2022 21:13:45 +0900</pubDate>
    </item>
    <item>
      <title>ssh - 추가인증 google authenticator (PAM)</title>
      <link>https://wooong-dev.tistory.com/entry/ssh-%EC%B6%94%EA%B0%80%EC%9D%B8%EC%A6%9D-google-authenticator-PAM</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;작업환경 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플랫폼 구글 클라우드&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제 Ubuntu Pro Server, ver 20&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신 유형 e2-medium(vCpu 2개, 8bg 메모리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;고민&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssh, rsa key 인증을 통해서 서버를 이용하고 있었는데 순간 내가 관리하는 키가 노출되면 어떻게 하지? 고민이 많아졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 ssh 보안을 강화하기로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 시스템에서는 PAM(인증 모듈: Pluggable Authenication Modules)을 제공함으로, 사용자의 권한, 인증을 제어하는 모듈 쓸 수 있게 환경을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 필요한 패키지를 설치하여, 2차인증을 강화하기로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은 총 2가지로 쓰일 것 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ssh 접속 요청 -&amp;gt; ssh 아이디, 비밀번호 -&amp;gt; otp 입력 -&amp;gt; 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. ssh rsa key 접속 요청 -&amp;gt; phrase 구문 입력 -&amp;gt; otp 입력 -&amp;gt; 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통사항에서 입맛에 맞춰서 설정값 1, 2번에 맞춰서 진행하면 됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;공통사항&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 이용 가능한 패키지, 버전 리스트 업데이트 및 설치된 패키지 버전 업그레이드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1641555431874&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update 

sudo apt upgrade&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 구글 PAM 설치&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1641555440565&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt install libpam-google-authenticator&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 구글 authenticator. configure&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1641555445533&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;google-authenticator&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;답변은 원하는 것을 맞춰서 고르면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1641554238827&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Do you want authentication tokens to be time-based (y/n) y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;time-based token, 시간 기반 일회용 암호를 사용할 것이냐고 물어본다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 답변은 y&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1641554416481&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Do you want me to update your &quot;/home/user/.google_authenticator&quot; file? (y/n) y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것은 키와 옵션 값이 지정한 경로에 적힌 파일에 업데이트된다는 것을 의미합니다. 만약 no를 누른다면, 선택은 종료됩니다. 즉, 구글 OTP를 이용 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 답변은 y&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1641554736635&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필수: 이때 나오는 QR 코드나 인증코드로 구글 OTP를 추가하면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30초마다 한 번만 로그인하게 제한합니다. 이것은 main-in-the-middle 공격을 방지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 답변은 y&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1641555170576&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.

Do you want to do so? (y/n) n&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간을 동기화하면서 발생할 수 있는 시간상 오차를 방지할 수 있는 옵션으로, 즉, 시간 오차를 허용할 것인지, 안 할 것 인지 물어보는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1641555277044&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션은 매 30마다 생성되는 토큰을 총 3번 이상 실패할 경우, 로그인을 차단하는 옵션입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# OpenSSH Configure&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo vi /etc/pam.d/sshd&lt;/p&gt;
&lt;pre id=&quot;code_1641555508885&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Standard Un*x password updating.
@include common-password
auth required pam_google_authenticator.so nullok&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 설치했던, pam otp 모듈을 설정하고, 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo vi /etc/ssh/sshd_config&lt;/p&gt;
&lt;pre id=&quot;code_1641555706665&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication yes&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정하고 저장합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1641555831564&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl restart sshd.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정해두었던 것을 적용하기 위해서 sshd서비스를 재시작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo vi /etc/ssh/sshd_config&lt;/p&gt;
&lt;pre id=&quot;code_1641557362988&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;UsePAM yes
# AuthenticationMethods publickey,password publickey,keyboard-interactive
AuthenticationMethods publickey,keyboard-interactive&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;otp를 모두 다&amp;nbsp; 요구를 하는데, 사용할 방법만 쓰는 것을 추천합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo vi /etc/pam.d/sshd&lt;/p&gt;
&lt;pre id=&quot;code_1641557833721&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Standard Un*x authentication.
#@include common-auth&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PAM에서 주석 처리를 진행하지 않으면 비밀번호를 물어봅니다. 그래서 주석처리를 진행한 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 Key + 2차 인증을 진행하고 싶기 때문이죠, 따라서 필요한 것만 진행하고 싶어서 주석 처리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 설정 사항을 다시 적용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1641557918789&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl restart sshd.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재접속을 진행해 OTP 적용이 잘되는지 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-07 at 9.21.17 PM.png&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ykz4H/btrp7SJiEkZ/KUGm8r7kRyFE0bkERYyY61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ykz4H/btrp7SJiEkZ/KUGm8r7kRyFE0bkERYyY61/img.png&quot; data-alt=&quot;적용 성공!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ykz4H/btrp7SJiEkZ/KUGm8r7kRyFE0bkERYyY61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fykz4H%2Fbtrp7SJiEkZ%2FKUGm8r7kRyFE0bkERYyY61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;736&quot; height=&quot;115&quot; data-filename=&quot;Screen Shot 2022-01-07 at 9.21.17 PM.png&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;115&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;적용 성공!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제 예전보다 보안이 강화되었습니다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>PAM</category>
      <category>SSH</category>
      <category>보안강화</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/20</guid>
      <comments>https://wooong-dev.tistory.com/entry/ssh-%EC%B6%94%EA%B0%80%EC%9D%B8%EC%A6%9D-google-authenticator-PAM#entry20comment</comments>
      <pubDate>Fri, 7 Jan 2022 21:20:20 +0900</pubDate>
    </item>
    <item>
      <title>Shell - 명령어 출력에서 단어 찾기</title>
      <link>https://wooong-dev.tistory.com/entry/Shell-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%B6%9C%EB%A0%A5%EC%97%90%EC%84%9C-%EB%8B%A8%EC%96%B4-%EC%B0%BE%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;명령어 출력에서 단어가 시작하는 해당 문자를 검색하기&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제는 깃허브 커밋 메세지에서 해당 찾고 싶은 메세지 문자열을 찾기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shell 명령어, grep, if, for 을 통해서 찾는 것을 성공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1641460956849&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for ((i=0;i&amp;lt;=10000;i++))
do
echo &quot;1&quot; &amp;gt;&amp;gt; index.js; 
git add .;
if git commit -m &quot;mining&quot; | grep &quot;\&amp;lt;00&quot;; then break; else echo &quot;&quot;; fi
done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브에 커밋 메세지를 만들어야 하기 때문에, 파일을 계속해서 수정하면서 커밋 메시지를 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1641460802644&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# shell 문법 for 반복문
# 문법이 여러가지인데, 제일 많이 사용하는 문법으로 시작
# 까다로운 점은 do done을 통해서 시작과 끝을 맺어줘야합니다.

# 100번 반복
for ((i=0; i&amp;lt;100; i++)) 
do
echo &quot;hi&quot;
done


# echo 문
# echo 문은 간단하게 터미널에 문자열을 출력하기 위함이며, echo 문을 이용해서 
# index.js 파일에 계속해서 append를 해줬습니다.

# index.js 파일에 1 더하기
echo &quot;1&quot; &amp;gt;&amp;gt; index.js

# if문
# if 문은 반복문을 돌리다가 해당 문자열을 찾을 경우 중단이 필요했기 떄문에, 사용
# 문법은 if 그리고 끝맺음은 fi로 끝을 맺어줘야합니다.

# 조건식과
if [ls | grep &quot;&amp;gt;\00&quot;]; 
then
	실행;
else 
	실행;
fi



# shell 문법 if

# grep 문자열 검색
# grep의 경우 문자열 처음 시작하는 문자열을 매칭해 검색을 가능하게 했습니다.
# 00으로 시작하는 문자열을 찾고 싶었습니다.


# 커밋 터미널 명령어 출력 메세지중에 grep을 통하여 00으로 시작하는 단어를 찾을 수 있었습니다.
git commit -m &quot;mining&quot; | grep &quot;\&amp;lt;00&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-01-06 at 6.30.50 PM.png&quot; data-origin-width=&quot;228&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NPDgg/btrpYmSa2uA/0lf6FKAs4pA7KzFBNYA7I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NPDgg/btrpYmSa2uA/0lf6FKAs4pA7KzFBNYA7I0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NPDgg/btrpYmSa2uA/0lf6FKAs4pA7KzFBNYA7I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNPDgg%2FbtrpYmSa2uA%2F0lf6FKAs4pA7KzFBNYA7I0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;228&quot; height=&quot;108&quot; data-filename=&quot;Screen Shot 2022-01-06 at 6.30.50 PM.png&quot; data-origin-width=&quot;228&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 문자열을 검색에 성공한 내용만 출력하여 해당 문자열에서 반복문 정지하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속해서 단일적으로 노동력을 소비하지 않고, 반복문을 통해서 해결할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;활용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문법을 통해 다양한 곳에서 활용이 가능하며, 개발하다가 문제로 00으로 시작하는 해쉬 열이 필요해서 찾게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 실용적이고, 활용적인 곳에서, 예를 들면 rest api 의 response 메시지 등에서 활용해볼 수 있겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>shell</category>
      <category>개발하다 만난 삽질</category>
      <category>우연히</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/19</guid>
      <comments>https://wooong-dev.tistory.com/entry/Shell-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%B6%9C%EB%A0%A5%EC%97%90%EC%84%9C-%EB%8B%A8%EC%96%B4-%EC%B0%BE%EA%B8%B0#entry19comment</comments>
      <pubDate>Thu, 6 Jan 2022 18:20:19 +0900</pubDate>
    </item>
    <item>
      <title>dream hack x86 Assembly Essential Part(1) 리뷰 -  개인분석</title>
      <link>https://wooong-dev.tistory.com/entry/dream-hack-x86-Assembly-Essential-Part1-%EB%A6%AC%EB%B7%B0-%EA%B0%9C%EC%9D%B8%EB%B6%84%EC%84%9D</link>
      <description>&lt;pre id=&quot;code_1640189908744&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Register]
rcx = 0 
rdx = 0
rsi = 0x400000
=======================

[Memory]
0x400000 | 0x67 0x55 0x5c 0x53 0x5f 0x5d 0x55 0x10
0x400008 | 0x44 0x5f 0x10 0x51 0x43 0x43 0x55 0x5d
0x400010 | 0x52 0x5c 0x49 0x10 0x47 0x5f 0x42 0x5c
0x400018 | 0x54 0x11 0x00 0x00 0x00 0x00 0x00 0x00
=======================

[code]
1: mov dl, BYTE PTR[rsi+rcx] (rsi+rcx 주소에서 1byte만큼 가져옵니다. (0x400000의 경우 0x67))
2: xor dl, 0x30 (dl과 0x30 xor 진행)
3: mov BYTE PTR[rsi+rcx],  (dl을 1byte(rsi+rcx)에 입력)
4: inc rcx (rcx 1증가)
5: cmp rcx, 0x19 (rcx, 0x19 비교)
6: jg end (rcx가 클 시, end 그렇지 않으면 7번 라인 이동)
7: jmp 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5번 라인. rcx, 0x19를 비교합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6번 라인. rcx가 0x19보다 클 시, 종료됩니다. 그렇지 않으면, 7번 라인으로 이동합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속해서 rcx는 20이 되도록 증가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0x400000 ~ 0x400019 부분마다 0x30을 XOR을 하며 진행합니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/어셈블리어</category>
      <category>개인분석</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/18</guid>
      <comments>https://wooong-dev.tistory.com/entry/dream-hack-x86-Assembly-Essential-Part1-%EB%A6%AC%EB%B7%B0-%EA%B0%9C%EC%9D%B8%EB%B6%84%EC%84%9D#entry18comment</comments>
      <pubDate>Thu, 23 Dec 2021 01:31:21 +0900</pubDate>
    </item>
    <item>
      <title>react useEffact</title>
      <link>https://wooong-dev.tistory.com/entry/react-useEffact</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;
&lt;h1&gt;useEffect 정의&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;useEffect&lt;/code&gt;는 useEffect Hook을 이용하여 React 컴포턴트가 렌더링 이후에 어떤 수행해야하는지 알려주는 역할을 합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;useEffect 종류&lt;/h1&gt;
&lt;pre class=&quot;arcade&quot;&gt;&lt;code&gt;
// 1. useEffect  기본적인 형태 -&amp;gt; 첫번째 렌더링과 모든 업데이트에서 수행 
useEffect(() =&amp;gt; {});


// 2. useEffect [] 렌더링 이후 단 한번 실행
useEffect(() =&amp;gt; {}, []);


// 3. useEffect [content] 해당 배열안의 요소가 변경되었을 때 실행 
useEffect(() =&amp;gt; {}, [content]);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;[content]&lt;/code&gt;에는 값이 변경되었을 때, 실행하게 만들고 싶을 때, 사용하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지중 하나를 골라서 필요한 것을 쓰면 될 것 같습니다.&lt;/p&gt;
&lt;/div&gt;</description>
      <category>etc/개발하다가 만난 삽질</category>
      <category>React</category>
      <category>useEffect</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/17</guid>
      <comments>https://wooong-dev.tistory.com/entry/react-useEffact#entry17comment</comments>
      <pubDate>Thu, 2 Dec 2021 01:47:22 +0900</pubDate>
    </item>
    <item>
      <title>GO - errors new 에러 핸들링</title>
      <link>https://wooong-dev.tistory.com/entry/GO-errors-new-%EC%97%90%EB%9F%AC-%ED%95%B8%EB%93%A4%EB%A7%81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;에러 핸들링은 무결성의 한 부분으로 아주 중요한 부분이다.&lt;br /&gt;에러&amp;nbsp;핸들링을&amp;nbsp;하지&amp;nbsp;않으면,&amp;nbsp;비정상적으로&amp;nbsp;종료될&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Example&lt;/h3&gt;
&lt;pre id=&quot;code_1638275326778&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Package  provides ...
package main

import (
	&quot;errors&quot;
	&quot;fmt&quot;
)

func div(a, b int) (int, error) { // a와 b를 입력받고 error하고 new를 리턴한다.
  if b == 0 {
    return 0, errors.New(&quot;It can't be divied by zero&quot;) // errors를 리턴한다.
  }
  return a / b, nil // b가 0이 아닐 경우에는 erorr는 nil
}



func main() {
  var (
    x = 100
    y = 0
  )

  v, err := div(x, y) // 100과 0을 funcion 매겨변수로 넘겨준다.
  if err != nil {
    fmt.Println(err.Error()) // nil이 아닐경우 에러를 출력합니다.
  }

  if err == nil {
    fmt.Print(v)
  }

}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;errors.New - Document&lt;/h3&gt;
&lt;pre id=&quot;code_1638276592030&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package errors

// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
	return &amp;amp;errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
	s string
}

func (e *errorString) Error() string {
	return e.s
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;errors.New를 생성하면 errorString struct를 반환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>언어/GO</category>
      <category>error</category>
      <category>go</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/16</guid>
      <comments>https://wooong-dev.tistory.com/entry/GO-errors-new-%EC%97%90%EB%9F%AC-%ED%95%B8%EB%93%A4%EB%A7%81#entry16comment</comments>
      <pubDate>Tue, 30 Nov 2021 21:51:53 +0900</pubDate>
    </item>
    <item>
      <title>curl 명령어 정리 - example, 코드 예시</title>
      <link>https://wooong-dev.tistory.com/entry/curl-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-example-%EC%BD%94%EB%93%9C-%EC%98%88%EC%8B%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;curl 옵션 정리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1638254601205&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# curl 관련 주로 쓰는 옵션 
curl 
      &amp;lt;&amp;gt; = 기입할 내용

      -d, --data &amp;lt;data&amp;gt;
      post 요청시 &amp;lt;data&amp;gt;에 요청 기입

      -f, --fail
      curl 명령 실패 무출력

      -h, help &amp;lt;category&amp;gt;
      post, upload, file 등등 옵션을 보여줍니다.

      -o, --output &amp;lt;file&amp;gt;
      아웃풋된 내용을 파일에 적어준다. 파일을 

      -s, --silent
      프로그래스바를 보여주지 않습니다.

      -A, --user-agent &amp;lt;name&amp;gt;
      user-agnet를 기입하면 됩니다.

      -V version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GET, POST 요청 - 예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;GET&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GET은 URL에 인자값을 붙여서 요청합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1638254841345&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl http://example-site.com/search?q=test&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;POST&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;POST는 BODY 부분에 인자값을 넣어서 요청합니다. 따라서 옵션을 넣어서 진행할 필요가 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1638255224643&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기본 형식
curl --data 'property=data' http://example-site.com/search

# JSON 형식
curl --data '{&quot;property&quot;:&quot;data&quot;}' --header 'Content-Type: application/json' \
	http://example-site/search&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 REST client 도구들이 많다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 도구들이 많지만,&amp;nbsp; curl command도 sh파일로 스크립트를 짜서 보낼 수&amp;nbsp; 있어서 좋은 부분이 있다.&amp;nbsp;&lt;/p&gt;</description>
      <category>etc/명령어 정리</category>
      <author>coti-z</author>
      <guid isPermaLink="true">https://wooong-dev.tistory.com/15</guid>
      <comments>https://wooong-dev.tistory.com/entry/curl-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-example-%EC%BD%94%EB%93%9C-%EC%98%88%EC%8B%9C#entry15comment</comments>
      <pubDate>Tue, 30 Nov 2021 15:54:44 +0900</pubDate>
    </item>
  </channel>
</rss>