<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yonaaaaaaa_a.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 07 Mar 2022 08:52:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yonaaaaaaa_a.log</title>
            <url>https://velog.velcdn.com/images/yonaaaaaaa_a/profile/cc6d0e53-a8f9-4adc-b049-f2018bf9ee29/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. yonaaaaaaa_a.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yonaaaaaaa_a" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[P2. Web2.0 Blockchain Community 클론코딩]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/P2.Web2.0-Blockchain-Community-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9</link>
            <guid>https://velog.io/@yonaaaaaaa_a/P2.Web2.0-Blockchain-Community-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9</guid>
            <pubDate>Mon, 07 Mar 2022 08:52:38 GMT</pubDate>
            <description><![CDATA[<h2 id="web20-blockchain-community">Web2.0 Blockchain Community</h2>
<p><a href="https://github.com/codestates/beb-02-MangoBeer">Github 주소</a>
<a href="https://www.notion.so/Project-2-32c92111d9f44ff8b79357a48782a96512312312"><del>Notion 페이지</del></a> 는 너굴맨이 먹어버림..🐻</p>
<h2 id="프로젝트-진행-과정">프로젝트 진행 과정</h2>
<h3 id="주요-기술스택">주요 기술스택</h3>
<ul>
<li>Client - React</li>
<li>DB - MySQL (sequelize)</li>
<li>Server - Nodejs, Express, Web3.js, ipfs</li>
<li>ganache</li>
<li>daemon</li>
</ul>
<hr>
<p>2주간 두번째 프로젝트를 진행하였다.</p>
<p>팀 배정이 끝난 이후 가장 어렵고 중요한 팀 이름 짓기를 성공적으로 마무리하였다.</p>
<p>첫번째 프로젝트때는 사다리 타기를 제안했었기에 이번에는 눈 앞에 보이는 사물을 이야기하고 서로 합치기로했다.</p>
<p>망고랑 맥주가 합쳐져서 <strong>Mangobeer🥭</strong> 가 되었다.</p>
<p>이번 프로젝트 주제는 <strong>인센티브 기반 커뮤니티</strong> 로 사용자가 한 행동에 대한 보상으로 토큰을 지급하고,</p>
<p>발급된 토큰으로 사용자들끼리의 토큰이코토미 생태계를 만들어나가는 것이었다.</p>
<p>아래와 같은 기능을 하도록 하는 프로젝트를 만들어내기로 하였다.</p>
<ul>
<li>사용자의 행위 : 회원가입-로그인 / 글 쓰기, 댓글 작성 (TOKEN 지급)</li>
<li>토큰 이코토미 : TOKEN을 이용한 NFT 거래 기능, TOKEN 전송 기능</li>
</ul>
<p>이해를 돕기위해 현재 나와있는 서비스를 예로 들자면 <a href="https://steemit.com/">스팀잇</a>, <a href="https://talken.io/main">톡큰</a>, <a href="https://www.a-ha.io/">아하</a> 와 유사하다고 볼 수 있다.</p>
<p>이 프로젝트를 성공적으로 수행하는데 있어서 핵심은 <strong>사용자 계정 관리를 도와주는 서버 개발</strong> 부분이었지 않을까 생각한다.</p>
<p>우선 프론트부분은 팀원분께서 진행해주셨는데 와이어프레임부터해서 뚝딱 만들어와주셨다.</p>
<p>1주차에 <strong>회원가입, 로그인, 글 쓰기, 댓글 쓰기</strong> 를 가능한 <strong>게시판 페이지</strong> 를 구현해냈다.</p>
<p>그 이후로는 <strong>daemon / erc20 / erc721</strong> 으로 파트를 나누어서 진행을 하였다.</p>
<hr>
<h3 id="진행-도중-발생한-문제점">진행 도중 발생한 문제점</h3>
<p>엄청 많이 마주쳤다...</p>
<p>가장 기억에 남았던 문제중 하나를 뽑자면</p>
<p>NFT를 민팅하기 위해서 업로드된 이미지를 통해 ipfs로 cid 값을 갖고 url로 변환해주는 과정에서 이미지를 서버쪽으로 넘겨주는 과정에서 base64 string으로 자동으로 인코딩되는 문제였다.</p>
<p>1) 이미지 path 만 넘겨받아서 child_process 모듈을 사용해서 cid 값을 얻는 방법이면 될 것이라고 생각했다.</p>
<pre><code class="language-javascript">function get_cid(){
    const cid = execSync(`ipfs add --quieter --pin=false${img_path}`).toString().replace(/\n/g, &quot;&quot;)
    execSync(`ipfs files cp /ipfs/${cid}` + ` &quot;` + `${img_name}` + `&quot;`)

    return cid
}</code></pre>
<p>하지만 이미짜여진 react 코드에서 img 에서 패스만 넘겨받을수 있는 방법을 찾아보다가 포기했다.</p>
<p>결국,</p>
<p><a href="https://github.com/ipfs/js-ipfs/issues/3924">https://github.com/ipfs/js-ipfs/issues/3924</a> 참고하여 해결되었다.</p>
<pre><code class="language-javascript">import { fromString } from &#39;uint8arrays/from-string&#39;
//....
async function get_cid_withIpfs(nfturl){

    var matches =nfturl.match(/^data:.+\/(.+);base64,(.*)$/);
    var ext = matches[1];
    var base64_data = matches[2];
    const data = fromString(base64_data, &#39;base64&#39;);


    const {cid} = await client.add(data);
    const ipfsLink = &quot;https://ipfs.io/ipfs/&quot; +cid;
    console.log(ipfsLink);

    return ipfsLink;
}</code></pre>
<hr>
<h2 id="프로젝트-동작-화면">프로젝트 동작 화면</h2>
<hr>
<h2 id="회고">회고</h2>
<h4 id="keep">Keep</h4>
<h4 id="problem">Problem</h4>
<h4 id="try">Try</h4>
<hr>
<p>화이팅</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[P1. OpenSea 클론코딩]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/P1.-OpenSea-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9</link>
            <guid>https://velog.io/@yonaaaaaaa_a/P1.-OpenSea-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9</guid>
            <pubDate>Fri, 18 Feb 2022 07:55:08 GMT</pubDate>
            <description><![CDATA[<h2 id="opensea-클론코딩">Opensea 클론코딩</h2>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/e3c8af32-7089-4770-8f44-8ea88fb0a251/image.png" alt=""></p>
<p><a href="https://github.com/codestates/BEB_02_ladder">Github 주소</a></p>
<h2 id="프로젝트-진행-과정">프로젝트 진행 과정</h2>
<p>개인 과제를 마치고 드디어 프로젝트를 하게 되었다</p>
<p>어색한 분위기속에서 가볍게 각자의 소개를 마치고 팀장과 팀명을 정하였다</p>
<p>NFT 거래소인 <a href="https://opensea.io/">Opensea</a> 를 클론코딩하는것이 첫번째 과제로 주어졌다</p>
<p>프로젝트를 진행하기에 앞서 예제로 주어진 코드를 따라하며 감을 익혀보았다</p>
<p>하지만 이걸로 무엇을 해야한다는거지 싶을정도로 감이 안잡힐뿐더러</p>
<p>소스코드를 작성하면서도 몇몇 에러들을 마주쳤고 해결하는데 오랜시간이 걸렸다</p>
<h3 id="첫번째-이슈">첫번째 이슈</h3>
<h4 id="error-cannot-find-module-">Error: Cannot find module &#39;!@#@!#&#39;</h4>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/37285f39-5801-4642-9cbe-2b9204036583/image.png" alt=""></p>
<p>분명 <code>npm install web3</code> 도 진행하고 정상적으로 <code>import</code> 되어있는 것 까지 확인하였는데 module 에러가 발생하였고, 아래 모듈들을 전체 설치한 뒤에 <code>package.json</code> 에서 &quot;react-scripts&quot;: &quot;5.1.3&quot;  이 부분에서 버전을 5 미만으로 낮추니 해결되었다.</p>
<blockquote>
<p>$ npm install https-browserify 
url 
stream-http 
crypto-browserify 
stream-browserify 
os-browserify 
stream 
eth-lib 
web3-eth-accounts 
web3 
assert
이후
pacakage.json 에서 &quot;react-scripts&quot;: &quot;4.0.0&quot; 으로 수정</p>
</blockquote>
<h3 id="두번째-이슈">두번째 이슈</h3>
<h4 id="typeerror-tokencontractmethodsname-is-not-a-function">(TypeError): tokenContract.methods.name is not a function</h4>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/d259204b-40be-41b7-8306-a902bfdc8df7/image.png" alt=""></p>
<p>컨트랙트에서 mint하여 발행된 nft를 확인할 수 있는 기능 -
컨트랙트 주소를 입력 후 &quot;add new erc721&quot; 버튼 클릭 시 제대로 동작하지 
않는 이슈가 있었다</p>
<blockquote>
<p>remixIDE 에서 ABI 코드를 복사할 때 컨트랙트명을 잘 확인한 뒤에 ABI코드를 가져와야한다.</p>
</blockquote>
<p>추가적으로, 컨트랙트를 배포하기 전</p>
<pre><code>function mintNFT(address recipient, string memory tokenURI) 
public onlyOwner returns (uint256) {</code></pre><p>같은 오류도 에러 문구도 발생하였으나 deploy 를 진행하는데는 이상이 없었다. (찾아보니 경고 메세지라고 한다)</p>
<hr>
<p>예제 코드를 어느정도 이해를 마치고,</p>
<p>첫번째로 Opensea 홈페이지에 들어가서 어떤 기능을 갖고있는지 자세히 탐구해보았다</p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/41210901-227a-4c62-ae29-073c7f17e437/image.png" alt=""></p>
<p>정리를 해보자면 주된 기능은 아래와 같았다</p>
<ul>
<li>NFT 와 Account 를 검색할 수 있는 검색창</li>
<li>OPENSEA에 등록된 모든 NFT를 볼 수 있는 Explore</li>
<li>NFT 의 가격순위와 활동같은 상태를 보기 위한 Stats</li>
<li>Opensea 에 대한 소개와 정보가 나열되어있는 Resources</li>
<li>NFT 를 발행하고, OPENSEA 거래소에 등록할 수 있는 Create</li>
<li>본인이 소유하고 있는 item을 보기 위한 Account</li>
<li>월렛 연결을 위한 Connect Wallet 버튼</li>
</ul>
<p>이 중 우리가 주어진 시간과 구현할 수 있을 기능만을 골라 개발을 진행하기로 하였다</p>
<p>_오픈씨는 NFT를 거래하는 곳 인데, 판매를 하기위해 판매자가 가격(Eth)을 설정하고 시장에 등록하는 과정(creat/listing)이 가장 중요하다고 생각은 했지만.... 어떻게 해야하지?
_</p>
<p>시간이 없어서 우선 싱글페이지로 제작하기로하였고 목업을 만들었다.</p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/1d47843c-6f5e-411b-b265-94b00a233478/image.png" alt=""></p>
<p>프로젝트와 팀을 소개하는 <code>Team</code>, <code>Intro</code></p>
<p>내가 소유하고 있는 NFT를 볼 수 있는 <code>MyCollection</code>
➡️ 이 부분에서 전송/등록 까지 진행하고자 하였다</p>
<p>지갑연결을 위한 <code>Wallet Connect</code>
➡️ <em>지갑 연결을 했으면 unconnect 기능도 있어야하는거 아니야?!!! 어떻게함?</em></p>
<p>뭘 해야될지는 알겠으나 막상 시작해보니 할 수 있는건 없었다...</p>
<p>결국 기능을 제대로 구현해보지도 못하였다.</p>
<hr>
<h2 id="프로젝트에서의-역할">프로젝트에서의 역할</h2>
<p>역할을 구분하지않아서 뭐를 맡았다라고 당당하게 얘기 할수는 없을 것 같다</p>
<p>자료수집, 프론트, 백엔드, 버전관리, 의사소통 전체적으로 다 진행하였다 (?)</p>
<h2 id="회고">회고</h2>
<p>물론 프로젝트를 100% 기능을 구현해내지는 못하였지만, 내가 그동안 배워왔던 기술들이 접목하여 어떤 결과물을 도출해낼수 있고 만들수있는지에 대해 간접적으로 경험할 수 있어서 만족스러웠다</p>
<p>항상 그렇지만 코딩실력이 많이 부족하다고 느끼고, 특히나 이번에는 웹쪽에서 많이 부족하다고 깨달았다</p>
<p>나 혼자서 진행하는 Github 레포지토리가 아닌 팀원들과 같이 진행한다는 경험도 처음이라 commit message 양식부터 branch와 merge를 통한 버전 관리가 중요하다는 점이 좋았다</p>
<p>이번 프로젝트를 통해서 아쉬웠던 부분과 가장 중요하다고 느낀 점은 바로 <strong>커뮤니케이션</strong> 이었다. 모르는 부분이 있을 때 문제를 공유함으로써 같이 해결하면서 혼자서 해결하는 것 보다 시간을 단축시킬수 있었으며 서로 의견공유를 통해 목표를 잡고 프로젝트를 진행한다면 더 좋은 결과물을 얻을 수 있었지 않았을까 생각이 든다</p>
<p>무뚝뚝하고 소심한 나의 성격상 팀원들과의 편안하고 원활한 소통을 할 수 있도록 분위기를 조성하는 것 또한 굉장히 중요하다고 느끼며....</p>
<p>첫번째 프로젝트 회고 끗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[yarn, create-react-app]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/yarn-create-react-app</link>
            <guid>https://velog.io/@yonaaaaaaa_a/yarn-create-react-app</guid>
            <pubDate>Wed, 09 Feb 2022 15:02:24 GMT</pubDate>
            <description><![CDATA[<h2 id="yarn">yarn</h2>
<p><strong>yarn 설치, 버전 확인</strong></p>
<pre><code class="language-linux">$ brew install yarn

$ yarn -version
1.22.17</code></pre>
<p><strong>yarn 초기화</strong></p>
<pre><code>$ mkdir sample
$ cd sample
$ yarn init
$ ls
package.json    yarn-error.log</code></pre><p><strong>yarn 패키지 관리</strong></p>
<pre><code>$ yarn install 

$ yarn add &lt;package&gt;

$ yarn remove &lt;package&gt; or yarn add —dev &lt;package&gt;

$ yarn upgrade

$ yarn ls</code></pre><p>yarn 명령어 : <a href="https://yarnpkg.com/cli/install">https://yarnpkg.com/cli/install</a>
yarn 구성 : <a href="https://classic.yarnpkg.com/en/docs/configuration">https://classic.yarnpkg.com/en/docs/configuration</a></p>
<h3 id="yarnlock">yarn.lock</h3>
<p>패키지 잠금 파일(.lock) 로써 프로젝트에 패키지에 최초로 추가하는 시점이 어떤 버전이 설치가 되었는지 기록되는 파일이다. <code>yarn install</code> 명령어를 활용하여 패키지를 설치하거나 삭제하는 경우 자동으로 <code>package.json</code> 과 <code>yarn.lock</code> 에 반영이 되기 때문에 절대로 수동으로 수정하지 않도록 한다.
<strong>⭐️ github과 같은 버전 관리 시스템에 프로젝트를 커밋할 때 반드시 yarn.lock 을 포함해야한다</strong></p>
<h2 id="create-react-app">create react-app</h2>
<pre><code class="language-linux">$ yarn create react-app hello-react
$ cd hello-react
$ yarn start </code></pre>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/304c7e43-baea-4bfe-a6a1-1f3f88adaaa1/image.png" alt=""></p>
<p><code>create react-app</code> 을 통해서 간단하게 react 프로젝트를 생성할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[nodeJs, npm, yarn  개념 정리]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/nodeJs-npm-yarn-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@yonaaaaaaa_a/nodeJs-npm-yarn-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 09 Feb 2022 14:08:09 GMT</pubDate>
            <description><![CDATA[<h2 id="nodejs">nodeJs</h2>
<p>node.js는 2009년 Ryan Dahl에 의해 개발이 개발이 되었다.</p>
<p>원래 Javascript 는 웹 브라우저(크롬, 파이어폭스) 가 있어야지만 동작이 가능한 언어였다. </p>
<p><code>node.js</code> 가 나오기 전까지.</p>
<p><strong>즉, node.js는 자바스크립트를 브라우저 밖에서 사용할 수 있도록, 다양한 용도로 확장하기 위해 만들어진 것이다.</strong></p>
<p><a href="https://nodejs.org/ko/">https://nodejs.org/ko/</a></p>
<h2 id="npm-nvm-npx">npm, nvm, npx</h2>
<p><code>npm</code> : Node Package Manage 의 약자로, 자바스크립트를 위한 패키지 관리자이다.</p>
<p><a href="https://docs.npmjs.com/about-npm">https://docs.npmjs.com/about-npm</a></p>
<p><code>nvm</code> : Node Version Manager 의 약자로, Node.js의 버전을 관리하기 위한 도구이다.</p>
<p><code>npx</code>  : Node Package eXecute 의 약자로, 노드 패키지 실행시키는 도구이다.</p>
<p>?</p>
<p>설명이 잘 되어있는 예시가 있어서 가져와봤다.</p>
<blockquote>
<p>create-react-app을 설치하는 과정에서 npx가 아닌 npm으로 -g 설치를 하게되면 많은 문제가 생긴다. 
그 중 로컬 스토리지에 있는 패키지가 새로운 버전이 나왔을 경우, 이미 존재하는 패키지를 제거하고 다시 설치해야한다는 가장 큰 문제이다.
출처: <a href="https://pongsoyun.tistory.com/116">https://pongsoyun.tistory.com/116</a></p>
</blockquote>
<p>➡️ npm 보다 간결하게 사용되고, 패키지가 꼬이지 않기 위해서 1회성인 <code>npx</code> 를 사용한다.</p>
<h2 id="yarn">yarn</h2>
<p><code>yarn</code> : npm과 마찬가지로 package.json을 통해 의존 패키지를 구분하고 프로젝트에서 어떤 일을 할지 결정한다.</p>
<h2 id="npm-vs-yarn">npm vs yarn</h2>
<p><strong>npm의 한계</strong></p>
<ul>
<li>npm 저장소의 취약한 보안 이슈를 시작으로, 의존 패키지의 버저닝 이슈, 무엇보다 패키지가 많아짐에 따라 빌드 성능이 좋지 않다는 점이 가장 큰 문제이다.</li>
</ul>
<p><strong>yarn의 장점</strong></p>
<ul>
<li>다운로드한 패키지 캐시: yarn은 모든 패키지를 유저 디렉토리에 저장해 캐싱한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Unit4. Truffle을 이용한 ERC721 제작하기 ]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Unit4.-Truffle%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-ERC721-%EC%A0%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Unit4.-Truffle%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-ERC721-%EC%A0%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 09 Feb 2022 08:57:08 GMT</pubDate>
            <description><![CDATA[<h2 id="truffle이란">Truffle이란?</h2>
<p><code>Truffle</code>, 스마트 컨트랙트 개발 시 로컬환경에서 보다 쉽게 컴파일하고 배포 환경을 제공하는 프레임워크이다.</p>
<pre><code class="language-lunux">// truffle 설치
$ npm install -g truffle 

// truffle 버전 확인
$ truffle version</code></pre>
<p>npm 명령어를 통하여 설치를 진행할 수 있다.</p>
<h3 id="truffle-프로젝트-생성">Truffle 프로젝트 생성</h3>
<pre><code class="language-linux">$ mkdir sample
$ cd sample
$ truffle init</code></pre>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/ff3e0ec7-0637-4575-8e10-ae6ecba0a56a/image.png" alt=""></p>
<p><code>truffle-config.js</code> : truffle 설정 파일을 편집하여 네트워크 설정을 진행한다.</p>
<p>Truffle 테스트 네트워크와 연결하기 위해서는 약간의 수정 작업이 필요했다. (<a href="https://andresaaap.medium.com/how-to-deploy-a-smart-contract-on-a-public-test-network-rinkeby-using-infura-truffle-8e19253870c4">참고 자료</a>)</p>
<p>1️⃣ infura 회원가입 후 프로젝트 생성
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/fb9532f6-8c02-40e6-b89f-b305fd6cb7ce/image.png" alt=""></p>
<p>2️⃣ HDWalletProvider 설치</p>
<pre><code class="language-linux">$ npm install @truffle-hdwallet-provider</code></pre>
<p>3️⃣ truffle.js 수정
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/c8001ad9-1a56-4052-9df4-9c3c025cb1be/image.png" alt=""></p>
<p>💡 <code>$vi .secret</code> 메타마스크 계정의 private key를 입력해줘야한다.</p>
<p>4️⃣ 확인
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/27e14bed-1340-41e4-aae9-26bd83d7318d/image.png" alt=""></p>
<h2 id="erc-721">ERC-721</h2>
<p><code>ERC-721</code>  이란 요즘 흔히들 알고있는 NFT(Non funcgible Token, 대체불가토큰)을 의미한다. - <a href="https://velog.io/@yonaaaaaaa_a/ERC-721%EA%B3%BC-NFT#%EF%B8%8F-%EC%98%A4%ED%94%88%EC%9E%AC%ED%94%8C%EB%A6%B0-erc721-%EC%98%88%EC%A0%9C%EC%BD%94%EB%93%9C">이전의 작성한 글</a> 참고</p>
<p>openzeppelin(오픈재플린) - &quot;스마트컨트랙트를 개발을 위해 제공되는 라이브러리&quot; 를 이용하여 쉽고 빠르게 개발을 해볼것이다.</p>
<p><strong>openzeppelin 설치</strong></p>
<pre><code class="language-linux">$ npm install @openzeppelin/contracts</code></pre>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/9acebb63-4160-48f1-9117-2451019a4e89/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/9f2aa078-979c-4c7a-a87f-e658fc8eb7ae/image.png" alt=""></p>
<p>이제 <code>@openzeppelin/contracts</code> 안에 있는 라이브러리를 <code>import</code> 를 통하여 사용할 수 있게 되었다.</p>
<h3 id="erc-721-소스코드">ERC-721 소스코드</h3>
<pre><code class="language-javascript">//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
// contracts/MyNFT.sol
pragma solidity ^0.8.7;

import &quot;@openzeppelin/contracts/token/ERC721/ERC721.sol&quot;;
import &quot;@openzeppelin/contracts/utils/Counters.sol&quot;;
import &quot;@openzeppelin/contracts/access/Ownable.sol&quot;;
import &quot;@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol&quot;;

contract MyNFT is ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721(&quot;MyNFT&quot;, &quot;NFT&quot;) {}

    function mintNFT(address recipient, string memory tokenURI)
        public onlyOwner
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}
</code></pre>
<h2 id="truffle-배포-진행">truffle 배포 진행</h2>
<pre><code class="language-javascript">// migrations/1_initial_migration.js
const MyNFT = artifacts.require(&quot;MyNFT.sol&quot;);

module.exports = function (deployer) {
  deployer.deploy(MyNFT);
};
</code></pre>
<pre><code class="language-linux">$ truffle migrate --compile-all --network rinkeby</code></pre>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/5ce07771-913a-4474-b02d-f94c89b2d347/image.png" alt=""></p>
<pre><code class="language-linux">truffle(rinkeby)&gt; i.mintNFT(accounts[0], &quot;{URL 주소}&quot;)</code></pre>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/2dd2e28c-bee1-4ee0-861e-9844403eefcf/image.png" alt=""></p>
<pre><code>// 확인 방법
truffle(rinkeby)&gt; i.tokenURI(1)</code></pre><h2 id="회고">회고</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[Unit5. 백신접종 DID 개발]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Unit5.-%EB%B0%B1%EC%8B%A0%EC%A0%91%EC%A2%85-DID-%EC%A0%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Unit5.-%EB%B0%B1%EC%8B%A0%EC%A0%91%EC%A2%85-DID-%EC%A0%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 09 Feb 2022 00:39:24 GMT</pubDate>
            <description><![CDATA[<h2 id="did란">DID란?</h2>
<p><code>Decentralized Identity (탈중앙화 신원 증명)</code>, 이전에 작성한 글을 참고하면 될 듯 하다. -  <a href="https://velog.io/@yonaaaaaaa_a/DID">DID</a></p>
<p><strong>예시코드로 제공되어있는 졸업증명 DID를 참고하여, 백신시스템으로 변경해 보자.</strong></p>
<hr>
<h2 id="백신접종-did의-주요-기능">백신접종 DID의 주요 기능</h2>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/d0899ef9-3f16-4862-a715-98e467c0bc99/image.png" alt=""></p>
<ul>
<li>인증된 기관으로부터 백신 접종 증명서를 발급받을수 있다.</li>
<li>접종 여부 확인 / 백신 제조사 확인 / 접종일 확인</li>
</ul>
<h3 id="ownerhelper">OwnerHelper</h3>
<p>OwnerHelper, 특정 함수를 관리자만 사용할 수 있도록 설정하는 기능을 가지고있는 컨트랙트
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/e37e0153-9f12-4a69-93c9-b4513aabc3a0/image.png" alt=""></p>
<p><code>function transferOwnership()</code> : 관리자를 다른 address로 이전시키는 함수</p>
<h3 id="issuerhelper">IssuerHelper</h3>
<p>IssuerHelper, 백신 증명서를 발급해줄수있는 기관을 추가/삭제/확인 할 수 있는 기능을 가지고있는 컨트랙트
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/2ff577a5-c18f-4320-bf14-ba05cf7dc2e5/image.png" alt=""></p>
<p><code>function addIssuer()</code> : 백신 증명서를 발행할 수 있도록 인증기관을 추가하는 함수
<code>function getIssuer()</code> : 해당 기관이 인증되어있는 확인할 수 있는 함수 
<code>function delIssuer()</code> : ↔️ <code>addIssuer()</code></p>
<h3 id="vaccinedid">VaccineDID</h3>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/bf76cc59-0c67-4156-993f-39f176ef934d/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/33a23b01-dcde-4b2b-987d-d419af92dcf1/image.png" alt=""></p>
<p><code>function claimCredential()</code> : 
<code>function getCredential()</code> : </p>
<h2 id="결과">결과</h2>
<p><del>gif를 통해서 컨트랙트 동작방식을 설명하고싶었으나 pending 때문에 원활히 진행이 안될것같아서 사진으로 첨부함</del></p>
<p>Ropsten 테스트넷으로 배포진행하였고 컨트랙트 주소(0x7703015Df9E56853bed5Db550b335259a5a9e6f3)를 통해 <a href="https://ropsten.etherscan.io/address/0x7703015df9e56853bed5db550b335259a5a9e6f3#readContract">이더스캔</a> 에서 확인가능하다. 전체 소스코드는 <a href="https://github.com/WONSUNGJUN/beb-section04-ha4">깃허브</a> 에 올려두었다.</p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/3281069c-939d-431b-a399-4a80481817e5/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/b54d347c-13ba-4762-becb-d7ec93394446/ezgif-5-5b678ad1da.gif" alt=""></p>
<p><code>isIssuer</code> 를 통해서 해당 기관이 인증되어있는 기관인지 확인해볼 수 있다.
최초 발행자인 <code>owner</code> 는 true로 갖고있으며, 인증이 되어있지 않으면 false 값을 갖고있다.
address 값 파라미터로 갖는 <code>addIssuer</code> 를 실행하면 true 로 바뀐것을 확인할 수 있다.</p>
<hr>
<h2 id="회고">회고</h2>
<p>예제코드를 보면서 실습을 진행하였을 때는 간단하게 생각했었는데.... 막상 소스코드를 작성하다보니 그렇지않았음을 깨달았다. 지금까지 너무 복사붙혀넣기식의 진행을 했었나, 제대로 된 학습이 되지않았다고 생각한다.
위 기능말고 인증기관 추가, 백신타입 추가, 부작용으로 인한 미접종자 같은 추가하고싶은 기능들이 있었는데 코딩실력이 미치지않아서 진행하지 못했다는게 개인적으로 아쉬웠다.</p>
<p>꾸준히 공부해서 나중에 완벽하게 수정하도록 해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Github - fork 와 clone 의 차이]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Github-fork-%EC%99%80-clone-%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Github-fork-%EC%99%80-clone-%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Sun, 30 Jan 2022 13:10:54 GMT</pubDate>
            <description><![CDATA[<h1 id="2022-01-30-til">2022. 01. 30 TIL</h1>
<h2 id="fork">fork</h2>
<p>다른사람이 올린 저장소 상태를 그대로 복사해서 내 계정의 저장소로 복제하는 기능이다. (⭐️오픈소스에 기여할 수 있다)
pull request를 통해 origin에게 보내고, origin이 마음에 들면 받아들여 commit 또는 merge 된다.</p>
<h2 id="clone">clone</h2>
<p>원격 공간에서는 수정하거나 작업할 수 없기 때문에 작업할 local 공간에 내려받는 기능이다.</p>
<h3 id="fetch와-pull의-차이">fetch와 pull의 차이</h3>
<p>둘 다 원격 저장소의 내용을 가져오는데 사용된다.
fetch는 가져온 변경내용을 로컬에 영향을 미치지 않고, 병합(merge) 하기 전 확인하는 용도로 사용한다.</p>
<pre><code class="language-linux">$ git fetch {원격저장소 이름}</code></pre>
<p>pull은 가져온 변경내용을 로컬에 병합한다. 충돌이 일어나지않게 유의해야한다. (↔️ git push)</p>
<pre><code class="language-linux">$ git pull origin master</code></pre>
<h2 id="정리">정리</h2>
<p>fork : 타인의 원격 저장소를 내 원격 저장소(repositories)로 가져오는 것
clone : 어떤 원격 저장소를 내 local 저장소로 가져오는 것
협업을 위해 복사하는 경우에는 fork를 사용, 단순한 프로젝트를 복사하기 위해서는 clone을 사용한다.
어떤 사람들은 &quot;fork는 clone을 통해 프로젝트에 기여하기 위한 upstream 등의 remote를 설정하고 fetch 등의 작업을 하기 위한 일련의 행위&quot; 라고 말하기도 한다.</p>
<p>참고링크 : <a href="https://www.theserverside.com/answer/Git-fork-vs-clone-Whats-the-difference">https://www.theserverside.com/answer/Git-fork-vs-clone-Whats-the-difference</a>
<a href="https://www.toolsqa.com/git/difference-between-git-clone-and-git-fork/">https://www.toolsqa.com/git/difference-between-git-clone-and-git-fork/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[WEB3.0]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/WEB3.0</link>
            <guid>https://velog.io/@yonaaaaaaa_a/WEB3.0</guid>
            <pubDate>Wed, 26 Jan 2022 04:29:32 GMT</pubDate>
            <description><![CDATA[<h2 id="📔-web30">📔 Web3.0</h2>
<blockquote>
<p><strong>Web3.0 ...?</strong>
= Read + Wrtie + Own</p>
</blockquote>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/6b0ac064-936d-49ee-9d0b-24d8e12ea382/image.png" alt=""></p>
<h2 id="📔-web3js">📔 Web3.js</h2>
<p>블록체인과 상호작용하는 클라이언트를 개발하기 위해서 사용되는 라이브러리.
이더리움 블록체인과 <strong>JSON RPC</strong>를 사용하여 소통한다. </p>
<pre><code class="language-linux">$ npm install web3</code></pre>
<p>npm install 명령어를 통해 간단하게 설치가 가능하며,</p>
<p>web3.js 에는 다음과 같은 모듈이 있다.</p>
<pre><code class="language-linux">$ Web3.modules
&gt; {
    Eth: Eth(provider), // 이더리움 네트워크와 상호작용하기 위한 모듈
    Net: Net(provider), // 네트워크 속성과 상호작용하기 위한 모듈
    Personal: Personal(provider), // 이더리움 계정과 상호작용하기 위한 모듈 
    Shh: Shh(provider), // 귓속말 프로토콜(?)과 상호작용하기 위한 모듈
    Bzz: Bzz(provider), // Swarm 네트워크와 상호작용하기 위한 모듈
}</code></pre>
<h2 id="📔-infura인퓨라">📔 Infura(인퓨라)</h2>
<p>원격 이더리움 노드를 통해 이더리움 네트워크에 접근할 수 있게 해주는 서비스.</p>
<p><a href="https://infura.io/">https://infura.io/ </a> 회원 가입 이후,</p>
<p>Dashboard 에서 <strong>CREATE NEW PROJECT</strong> 로 하나의 프로젝트를 만들어준다.</p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/1c709932-e242-4006-9b16-49b31ea4fb4d/image.png" alt=""></p>
<p>위에 적힌 KEYS 부분에서 <strong>&quot;PROJECT ID&quot;</strong> 가 API Key와 같은 역할이다.</p>
<h2 id="⚙️-예시-코드">⚙️ 예시 코드</h2>
<h3 id="⚙️-getbalance---잔액-조회">⚙️ getBalance() - 잔액 조회</h3>
<pre><code class="language-javascript">const Web3 = require(&#39;web3&#39;);
const rpcURL =&quot;https://ropsten.infura.io/v3/{infura에서 발급받은 개인 key}&quot;

const web3 = new Web3(rpcURL);

const account = &quot;{개인 지갑 주소}&quot;;

web3.eth.getBalance(account).then((bal) =&gt; {
    console.log(`지갑 ${account}의 잔액은... ${bal} 입니다.`);
})</code></pre>
<pre><code class="language-linux">// 실행 결과
$ 지갑 0xd9Eba49d7A8073A779633a838e18589f4edBFe22의 잔액은... 5693033873293706590 입니다.</code></pre>
<p>지갑에 들어있는 Eth의 개수와는 달리 이상한 숫자가 나온다.</p>
<p>화폐의 단위가 이더(Eth)가 아닌 wei이기 때문이다.</p>
<p>web3.utils.fromwei()는 wei 단위를 화폐 단위로 변환을 해준다.</p>
<pre><code class="language-javascript">//...
web3.eth.getBalance(account).then((bal) =&gt; {
    console.log(`지갑 ${account}의 잔액은... ${bal} 입니다.`);
    return web3.utils.fromWei(bal, &quot;ether&quot;); // web3.utils.fromWei 추가
})
.then((eth)=&gt; {
    console.log(`이더 단위로는 ${eth} 입니다.`)
})</code></pre>
<pre><code class="language-linux">// 실행 결과
지갑 0xd9Eba49d7A8073A779633a838e18589f4edBFe22의 잔액은... 5693033873293706590 입니다.
이더 단위로는 5.69303387329370659 입니다.</code></pre>
<h3 id="⚙️-gettransaction-gettransactionreceipt--트랜잭션-조회">⚙️ getTransaction, getTransactionReceipt- 트랜잭션 조회</h3>
<pre><code class="language-javascript">const Web3 = require(&#39;web3&#39;);
const rpcURL =&quot;https://ropsten.infura.io/v3/{infura에서 발급받은 개인 key}&quot;

const web3 = new Web3(rpcURL);

const txId = &quot;{트랜잭션 해시 값}&quot;;

web3.eth.getTransaction(txId)
    .then((obj)=&gt; {
        console.log(obj);
});</code></pre>
<pre><code>// 실행결과 
{
  accessList: [],
  blockHash: &#39;0xb531433ffe59bd933a0ab4f9e979566cca81dc9149941f526362934010aa701f&#39;,
  blockNumber: 11855222,
     ...</code></pre><h3 id="⚙️-getblock---블록-조회">⚙️ getBlock - 블록 조회</h3>
<pre><code class="language-javascript">const Web3 = require(&#39;web3&#39;);
const rpcURL =&quot;https://ropsten.infura.io/v3/{infura에서 발급받은 개인 key}&quot;

const web3 = new Web3(rpcURL);

const blockNum = &quot;{block 번호}&quot;;

web3.eth.getBlock(blockNum)
    .then((obj)=&gt; {
        console.log(obj)
})
</code></pre>
<pre><code class="language-linux">// 실행 결과 - block이 갖고 있는 정보를 볼 수 있다.
{
  baseFeePerGas: 16,
  difficulty: &#39;2227247239&#39;,
  extraData: &#39;0xd883010a0f846765746888676f312e31372e35856c696e7578&#39;,
  gasLimit: 8000000,</code></pre>
<h3 id="🔨-gettransactionbyaccount---특정-주소의-거래-내역-조회">🔨 getTransactionByAccount - 특정 주소의 거래 내역 조회</h3>
<pre><code class="language-javascript">// 블록 범위에 있는 블록에 기록된 트랙잭션 중 해당 계정이 참여한 트랜잭션만 추출
// 인자로 주소값 account 와 블록 숫자로 이루어진 블록 범위값 startBlcok, endBlock을 인자로 갖는다.
// 해당 블록 범위 내에 송신 또는 수신자로 참여한 트랜잭션들로 구성된 배열 반환

const Web3 = require(&#39;web3&#39;);
const rpcURL =&quot;https://ropsten.infura.io/v3/{infura에서 발급받은 개인 key}&quot;

const web3 = new Web3(rpcURL);

function Solution(startBlock, endBlock, account) {

    transaction_box = []

    web3.eth.getBlock(startBlock, function(err, res) {
        if(!err) {
            for(let i=0; i&lt;res.transactions.length; i++) {
                transaction_box.push(res.transactions[i])
            }
        }

        for(let j=0; j&lt;transaction_box.length; j++) {
            //console.log(transaction_box[j])
            web3.eth.getTransaction(transaction_box[j], function(err1, res1) {
                if(!err1) {
                    if(res1.from === account) {
                        console.log(`${res1.from} 에서 ${res1.to} 로 보내줬다.`)
                    }
                    else if(res1.to === account) {
                        console.log(`${res1.to} 에서 ${res1.from} 로 받았다.`)
                    }
                }
            })
        }

    })
}

console.log(Solution(11855222, 11855225, &quot;0xd9Eba49d7A8073A779633a838e18589f4edBFe22&quot;))
</code></pre>
<p>대충 재귀로 돌려가지고 저런식으로 하면 될것같은데... 자바스크립트 잘 했으면 좋겠다... ㅠㅠㅠㅠㅠ</p>
<hr>
<h2 id="💡-참고-링크">💡 참고 링크</h2>
<p>1) <a href="http://channy.creation.net/blog/1509">http://channy.creation.net/blog/1509</a>
2) <a href="https://www.npmjs.com/package/web3">https://www.npmjs.com/package/web3</a>
3) <a href="https://web3js.readthedocs.io/en/v1.2.11/web3.html#web3-modules">https://web3js.readthedocs.io/en/v1.2.11/web3.html#web3-modules</a>
4) <a href="https://web3js.readthedocs.io/en/v1.2.11/web3-utils.html?highlight=fromWei#fromwei">https://web3js.readthedocs.io/en/v1.2.11/web3-utils.html?highlight=fromWei#fromwei</a> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Solidity 문법 정리 - 1]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Solidity-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-1</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Solidity-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-1</guid>
            <pubDate>Tue, 25 Jan 2022 08:54:35 GMT</pubDate>
            <description><![CDATA[<h2 id="📔-solidity">📔 Solidity</h2>
<blockquote>
<p><strong>Solidity (솔리디티)란?</strong>
이더리움의 스마트 컨트랙트를 구현하기 위해 사용되는 계약 지향 프로그래밍 언어이다...</p>
</blockquote>
<h2 id="📔-layout-of-a-solidity-source-file">📔 Layout of a Solidity Source File</h2>
<h3 id="pragma">pragma</h3>
<pre><code class="language-javascript">pragma solidity ^0.8.7; // ^ 이걸 넣어주면 0.8.7 버전 이후로는 다 실행 가능
or
pragma solidity &gt;=0.4.0 &lt; 0.6.0; // 범위내에 버전만 실행 가능</code></pre>
<p>solc 버전을 꼭 적어줘야한다.</p>
<h3 id="import">import</h3>
<pre><code class="language-javascript">import &quot;filename&quot;;
import * as SymbolName from &quot;filename&quot;;</code></pre>
<p>import 는 가져와서 쓸거 가져다 쓰면 된다.</p>
<h3 id="comments">Comments</h3>
<p>// or /* */ 을 통해 주석을 작성할 수 있다.</p>
<h2 id="📔-structure-of-a-contract">📔 Structure of a Contract</h2>
<h3 id="state-variables">State Variables</h3>
<pre><code class="language-javascript">contract example {
  uint exam_number; // 전역 변수</code></pre>
<h3 id="function">function</h3>
<pre><code class="language-javascript">contract example {
  function simplefunc { // 함수
    // ...</code></pre>
<p>function 함수 선언할 때 사용된다.</p>
<h3 id="modifier">modifier</h3>
<pre><code class="language-javascript">contract example {
  address public seller;

  modifire onlySeller() { // modifier 선언
    require(msg.sender == seler, &quot;only seller can call this.&quot;);
    _;
  }

  function abort() public view onlySeller { // modifier 사용
    //...
  }
}</code></pre>
<p>modifier 는 함수 변경자로 _; 을 만나기 전, _; 을 만났을 때 modifier 실행, _; 이후 실행된다.</p>
<h3 id="event">event</h3>
<pre><code class="language-javascript">contract example {
  event HighestBidIncreased(address bid, uint amount); // event 선언

  function bid() public payable {
    // ...
        emit HighestBidIncreased(msg.sender, msg.value); // event 트리거
  }
}</code></pre>
<p>기록남기기로 emit 을 만나면 event가 실행된다.</p>
<h3 id="struct">struct</h3>
<pre><code class="language-javascript">contract Ballot {
    struct Voter { // struct 
        uint weight;
        bool voted;
        address delegate;
        uint vote;
    }
}</code></pre>
<p>구조체다.</p>
<h3 id="enum">enum</h3>
<pre><code class="language-javascript">contract Purchase {
    enum State { Created, Locked, Inactive } // Enum
}</code></pre>
<p>열거형이다.</p>
<hr>
<h2 id="💡-참고링크">💡 참고링크</h2>
<p>1) <a href="https://solidity-kr.readthedocs.io/ko/latest/layout-of-source-files.html#experimental-pragma">solidity Docs</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DID ]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/DID</link>
            <guid>https://velog.io/@yonaaaaaaa_a/DID</guid>
            <pubDate>Tue, 25 Jan 2022 06:16:32 GMT</pubDate>
            <description><![CDATA[<h3 id="📔-diddecentralized-identifier">📔 DID(Decentralized identifier)</h3>
<blockquote>
<p><strong>DID란...?</strong>
탈중앙화 신원인증. 
토큰발행이 없는 경우가 있으며, 오로지 블록체인 기술을 &#39;활용한&#39; 신원 인증 서비스</p>
</blockquote>
<ul>
<li><a href="https://infrablockchain.com/ko/technology/">쿠브(COOV)</a>, <a href="https://www.iconloop.com/about/">아이콘루프(icon)</a> 등등과 같은 자격증, 사원증, 나를 증명할 수 있는 서비스 들이 DID에 속한다.</li>
</ul>
<p>기업의 데이터 집중화를 떠나, 개인데이터에 대한 소유권의 책임을 본인이 소유하고 개인 주권을 강화하자.</p>
<h3 id="📔-ssiself-soverin-identity">📔 SSI(Self-Soverin identity)</h3>
<p>개인이 디지털 상의 신원 주권을 가지게 될 때, 개인의 개인정보를 자신 스스로 소유하는 개념</p>
<ul>
<li>SSI가 구성하기 위한 4가지 요소<ul>
<li>Issuer(발행자)</li>
<li>Holder(소유자)</li>
<li>Verifier(검증자)</li>
<li>Verifiable data Registry(검증 데이터 저장소 ⇒ 블록체인)</li>
</ul>
</li>
</ul>
<hr>
<h3 id="⚙️-예시-코드">⚙️ 예시 코드</h3>
<pre><code class="language-javascript">//SPDX-License-Idetifier: MIT
pragma solidity ^0.8.10;

contract CredentialBox {
    address private issuerAddress;
    uint256 private idCount;
    mapping(uint8 =&gt; string) private alumniEnum;

    struct Credential {
        uint256 id;
        address issuer;
        uint8 alumniType;
        string value;
    }

    mapping(address =&gt; Credential) private credentials;

    constructor() {
        issuerAddress = msg.sender;
        idCount = 1;
        alumniEnum[0] = &quot;SEB&quot;;
        alumniEnum[1] = &quot;BEB&quot;;
        alumniEnum[2] = &quot;AIB&quot;;
    }

    // 증명서를 발행하기 위한 함수
    function claimCredential(address _alumniAddress, 
                            uint8 _alumniType,
                            string calldata _value) public returns(bool) {

                                require(issuerAddress == msg.sender, &quot;Not Issuer&quot;);
                                Credential storage credential = credentials[_alumniAddress];
                                require(credential.id == 0);

                                credential.id = idCount;
                                credential.issuer = msg.sender;
                                credential.alumniType = _alumniType;
                                credential.value = _value;

                                idCount += 1;

                                return true;
                            }

    // 받은 증명서를 확인하는 함수                        
    function getCredential(address _alumniAddress) public view returns (Credential memory){
        return credentials[_alumniAddress];
    }
}

//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWRwIjoiY29kZSBzdGF0ZXMiLCJ0eXBlIjoiYmViIiwidG9rZW4iOiJ0ZXN0IiwidmFsdWUiOiLsvZTrk5zsiqTthYzsnbTsuKAgRElEIOyImOujjOymnSDrsJzquInsnYQg7JyE7ZWcIO2BrOumrOuNtOyFnCDthYzsiqTtirgifQ.qXTgkPcK43uZ4_FBLBTFjaTsnmV9sAAekgK8BUZBt1g
//_value 값은 JWT로 암호화되어있음</code></pre>
<hr>
<h2 id="💡-참고링크">💡 참고링크</h2>
<p>1) <a href="http://wiki.hash.kr/index.php/%EB%B6%84%EC%82%B0%EC%95%84%EC%9D%B4%EB%94%94">탈중앙화 신원인증(DID)</a>
2) <a href="http://wiki.hash.kr/index.php/%EC%9E%90%EA%B8%B0%EC%A3%BC%EA%B6%8C%EC%8B%A0%EC%9B%90">자기주권신원(SSI)</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ERC-721과 NFT 개발]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/ERC-721%EA%B3%BC-NFT</link>
            <guid>https://velog.io/@yonaaaaaaa_a/ERC-721%EA%B3%BC-NFT</guid>
            <pubDate>Mon, 24 Jan 2022 07:48:10 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">Introduction</h2>
<h4 id="achievement-goals">Achievement Goals</h4>
<ul>
<li>ERC-721과 ERC-20의 차이점을 설명할 수 있다.</li>
<li>ERC-721에 포함된 함수별 기능을 이해할 수 있다.</li>
<li>ERC-721을 통한 NFT가 사용되는 방식을 설명할 수 있다.</li>
<li>NFT를 거래 또는 사용하는 플랫폼을 설명할 수 있다.</li>
<li>NFT의 거래 또는 사용 방식을 이해할 수 있다.</li>
<li>Remix, Truffle을 이용해 직접 ERC-721을 배포할 수 있다.</li>
<li>IPFS와 연동하여 NFT에 이미지를 저장하고, 배포할 수 있다.</li>
<li>클레이튼 기반의 NFT와 이더리움 기반의 NFT를 비교할 수 있다.</li>
<li>클레이튼 테스트넷에 NFT를 배포할 수 있다.</li>
<li>OpenSea에서 클레이튼 기반의 NFT와 이더리움 기반의 NFT를 거래할 수 있다.</li>
<li>Minting 플랫폼으로 NFT를 하는 방법을 이해할 수 있다.</li>
</ul>
<hr>
<h3 id="📔-erc-721">📔 ERC-721</h3>
<blockquote>
<p><strong>ERC-721 이란...</strong>
: 2018년 1월 <a href="https://twitter.com/fulldecent">William Entriken</a>,  <a href="https://twitter.com/dete73">Dieter Shirley</a>,  Jacob Evans, Nastassia Sachs 의 <a href="https://github.com/ethereum/eips/issues/721">EIP-721</a> 제안의 의해 2018년 6월 최종적으로 승인 받아 탄생하게 되었다. 
erc721을 요약하자면, 증서라고 하는 <strong>대체 불가능한 토큰</strong>에 대한 표준을 정의한 것이다.</p>
</blockquote>
<p>_+ Dieter Shirley는 CrpyotoKitties 를 제작하였으며, Dapper Labs의 설립자이자 Flow라는 블록체인의 설계까지 한 뛰어난 사람이다...
_</p>
<ul>
<li>ERC-721은 NFT를 추적하고 전송하는 기본 기능을 포함한다</li>
<li>고유한 속성을 지니고, 각각 구별할 수 있으며 소유권을 별도로 추적할 수 있어야 한다.</li>
</ul>
<h4 id="erc-721-과-erc-20을-구분하기-위해서는-erc-165-자체-검사를-수행하여야-한다">ERC-721 과 ERC-20을 구분하기 위해서는 ERC-165 자체 검사를 수행하여야 한다.</h4>
<blockquote>
<p><strong>ERC-165 란...</strong>
스마트 컨트랙트가 구현하는 인터페이스를 게시하고 있는지 감지하는 표준 방법이다. <a href="https://eips.ethereum.org/EIPS/eip-165#simple-summary">EIP-165</a></p>
</blockquote>
<h4 id="️-주의해야할-점-️">‼️ 주의해야할 점 ‼️</h4>
<ul>
<li>코드에서 for/while loop를 사용하지 말란다. 가스비가 무한으로 올라가는 이슈가있다고하니 필요한 경우에는 함수에서 solidity 배열 유형을 return 해주라고한다.</li>
<li>모든 메타데이터를 온체인상으로 올리기에는 너무 비싸다. </li>
<li>nft에서의 고유 식별은 uint256의 ID로 식별이되기때문에 단순하게 순차적으로 증가하는 패턴보다는 &quot;Black box&quot;로 취급해야한다. (아무도 볼 수없게 하라는 뜻인듯?...)</li>
</ul>
<hr>
<h2 id="⚙️-erc-721-표준-소스코드">⚙️ ERC-721 표준 소스코드</h2>
<pre><code class="language-javascript">pragma solidity ^0.4.20;

interface ERC721 {
  event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
  event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
  event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

  function balanceOf(address _owner) external view returns (uint256); // 해당 주소가 보유하고있는 nft갯수를 리턴
  function ownerOf(uint256 _tokenId) external view returns (address); // nft를 소유하고 있는 주소를 리턴
  function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; // 전송받는 to 주소가 erc721토큰을 받을수 있는지 체크하고 전달
  function transferFrom(address _from, address _to, uint256 _tokenId) external payable; // nft 소유자로부터 해당 nft를 다른 주소로 전송 
  function approve(address _approved, uint256 _tokenId) external payable; // 해당 주소에 nft 전송 권한을 부여
  function setApprovalForAll(address _operator, bool _approved) external; // nft 소유자가 해당 주소에게 모든 nft 에 대한 전송 권한 부여 및 해제
  function getApproved(uint256 _tokenId) external view returns (address); // 해당 토큰의 전송 권한을 갖고 있는 주소를 리턴
  function isApprovedForAll(address _owner, address _operator) external view returns (bool); // setApprovealForAll 의 권한이 있는지 true, false 리턴
}

interface ERC165 {
  function supportsInterface(bytes4 interfaceID) external view returns (bool);
}</code></pre>
<h3 id="⚙️-erc-721-tokenreceiver">⚙️ ERC-721 (TokenReceiver)</h3>
<pre><code class="language-javascript">interface ERC721TokenReceiver {
  function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
}</code></pre>
<h3 id="⚙️-erc-721-metadata">⚙️ ERC-721 (Metadata)</h3>
<pre><code class="language-javascript">interface ERC721Metadata {
  function name() external view returns (string _name);

  function symbol() external view returns (string _symbol);

  function tokenURI(uint256 _tokenId) external view returns (string);
}

/*
위 ERC721 Metadata 의 JSON 스키마 형태
{
    &quot;title&quot;: &quot;Asset Metadata&quot;,
    &quot;type&quot;: &quot;object&quot;,
    &quot;properties&quot;: {
        &quot;name&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;description&quot;: &quot;Identifies the asset to which this NFT represents&quot;
        },
        &quot;description&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;description&quot;: &quot;Describes the asset to which this NFT represents&quot;
        },
        &quot;image&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;description&quot;: &quot;A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.&quot;
        }
    }
}
*/</code></pre>
<h3 id="⚙️-선택사항-erc-721-enumerable">⚙️ /선택사항/ ERC-721 (Enumerable)</h3>
<pre><code class="language-javascript">interface ERC721Enumerable {
  function totalSupply() external view returns (uint256);
  function tokenByIndex(uint256 _index) external view returns (uint256);
  function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}</code></pre>
<h3 id="⚙️-오픈재플린-erc721-예제코드">⚙️ 오픈재플린 ERC721 예제코드</h3>
<pre><code class="language-javascript">// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import &quot;@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol&quot;;
import &quot;@openzeppelin/contracts/utils/Counters.sol&quot;;

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721(&quot;GameItem&quot;, &quot;ITM&quot;) {}

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}</code></pre>
<hr>
<p>** 각 function 마다 주석으로 어떤 기능을 수행하는지 간략하게 적어두었으니 확인하자
** ERC-721의 핵심은 uint256 =&gt; address 의 mapping 에 대해서 반드시 알아야함</p>
<hr>
<h2 id="💡-참고링크">💡 참고링크</h2>
<p>1) <a href="https://eips.ethereum.org/EIPS/eip-721">https://eips.ethereum.org/EIPS/eip-721</a>
2) <a href="https://github.com/ethereum/eips/issues/721">https://github.com/ethereum/eips/issues/721</a>
3) <a href="https://eips.ethereum.org/EIPS/eip-165#simple-summary">https://eips.ethereum.org/EIPS/eip-165#simple-summary</a>
4) <a href="https://soliditydeveloper.com/erc-721">https://soliditydeveloper.com/erc-721</a>
5) <a href="https://docs.openzeppelin.com/contracts/2.x/api/token/erc721">https://docs.openzeppelin.com/contracts/2.x/api/token/erc721</a>
6) <a href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol">https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol</a>
7) <a href="https://anallergytoanalogy.medium.com/jumping-into-solidity-the-erc721-standard-part-1-e25b67fc91f3">https://anallergytoanalogy.medium.com/jumping-into-solidity-the-erc721-standard-part-1-e25b67fc91f3</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Solidity 개발 환경 ]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Solidity-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Solidity-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD</guid>
            <pubDate>Sat, 22 Jan 2022 05:31:29 GMT</pubDate>
            <description><![CDATA[<p>📔 Solidity 개발환경을 맞추기 위한, 까먹지 않기 위한, 기록용 글 입니다.</p>
<p>가장 편리한 방법은 ropsten 또는 rinkeby 용 eth를 받아서 <a href="https://remix.ethereum.org/">remix IDE</a> 에서 개발을 하는 것 입니다. Test Ethereum을 받는 방법은 구글에 &#39;ropsten faucet&#39; 을 검색해보시고 어느 사이트를 들어간 뒤에 네트워크를 맞추고 메타마스크의 본인 address 를 넣어주시면 됩니다.</p>
<h3 id="개발-및-배포-과정">개발 및 배포 과정</h3>
<blockquote>
<p>TestRPC → TestNet → MainNet</p>
</blockquote>
<ul>
<li>TestRPC : 개발 진행 <em>(ganache)</em></li>
<li>TestNet : 개발 완료 후 메인넷과 동일환 환경에서 테스트 <em>(ropsten)</em></li>
<li>MainNet : 실제 서비스에 사용할 수 있도록 배포 <em>(mainet)</em></li>
</ul>
<h3 id="remixd">remixd</h3>
<p>remixd 는 본인의 로컬 저장소의 소스코드와 remix IDE와 connect을 하여서 파일 또는 git 관리를 용이하게 해준다.</p>
<h4 id="remixd-설치-및-실행">remixd 설치 및 실행</h4>
<pre><code class="language-linux">$ npm install -g remixd 
$ mkdir hello_solidity

$ remixd -s ~/hello_solidity https://remix.ethereum.org</code></pre>
<p>remixd 명령어를 통해 작업할 디렉토리를 지정해준 뒤 서비스 실행을 시켜준 뒤, remixd 와 remix IDE 에서의 자세한 연동방법은 아래 <a href="https://remix-ide.readthedocs.io/en/latest/remixd.html">링크</a> 를 통해 확인해보자.</p>
<h3 id="ganache">Ganache</h3>
<p>Ganache (가나슈) 는 하나의 테스트 블록체인 네트워크이다.</p>
<h4 id="ganache-설치-및-진행">ganache 설치 및 진행</h4>
<pre><code class="language-linux">$ brew install ganache</code></pre>
<p>brew 를 이용하여 간단하게 ganache 설치할 수 있다.
이후 생겨난 ganache 를 실행시켜 &#39;QuickSTART&#39; 또는 &#39;New Workspace&#39; 를 통해서 하나의 테스트 블록체인 네트워크와 100ETH가 들어있는 10개의 가상 address를 얻을 수 있다.
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/af64731b-5ed4-4c2c-aa8c-e916313373f0/image.png" alt=""></p>
<ul>
<li>RPC SERVER : HTTP://127.0.0.1:7545</li>
<li>NETWORK ID : 5777</li>
</ul>
<center><h1><span style ='color:red'> **여기서 잠깐!** </span></center></h1>

<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/8f2ba61a-bc5f-4243-a19a-3eb2584eb55b/image.png" alt=""></p>
<p>메타마스크를 통해 생성한 가나슈 네트워크를 등록해보자, 체인 ID 가 5777 로 등록이 안된다. 그 이유는 가나슈 역시 Localhost Network 에 등록되어있는 체인 ID를 따르기 때문인것 같다... 아님말고</p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/989e5f66-657f-44d8-bc3b-56c4cdfe9211/image.png" alt="">
그 이후로는 가상의 address 의 오른쪽 show key 버튼을 클릭하면 보이는 private key 를 통해서 metamask와 연결을 한다. 자세한 방법은 <a href="https://trufflesuite.com/tutorial/index.html#installing-and-configuring-metamask">링크</a>를 통해 확인해보자</p>
<p>이제 test-rpc 환경과 ide 개발 환경이 다 갖추어졌다.</p>
<h3 id="openzeppelin">openzeppelin</h3>
<p>오픈재플린은 안전한 스마트 컨트랙트 개발을 위한 라이브러리 이다.</p>
<h4 id="openzeppelin-설치">openzeppelin 설치</h4>
<pre><code class="language-linux">$ npm install @openzeppelin/contracts</code></pre>
<p>작업할 디렉토리에서 위 명령어를 통해서 openzeppelin 라이브러리를 설치할 수 있다.</p>
<pre><code>.
├── node_modules
│   └── @openzeppelin
│       └── contracts
│           ├── README.md
│           ├── access
│           │   ├── AccessControl.sol
│           │   ├── AccessControlEnumerable.sol
│           │   ├── IAccessControl.sol
│           │   ├── IAccessControlEnumerable.sol
│           │   └── Ownable.sol
│           ├── build
│           │   └── contracts
│           │       ├── AccessControl.json
│           │       ├── AccessControlEnumerable.json
│           │       ├── Address.json
│           │       ├── Arrays.json
│           │       ├── BeaconProxy.json
│           │       ├── BitMaps.json
│           │       ├── Clones.json
│           │       ├── ConditionalEscrow.json
│           │       ├── Context.json
│           │       ├── Counters.json
│           │       ├── Create2.json
│           │       ├── ECDSA.json
│           │       ├── EIP712.json
│           │       ├── ERC1155.json
│           │       ├── ERC1155Burnable.json
│           │       ├── ERC1155Holder.json
│           │       ├── ERC1155Pausable.json
│           │       ├── ERC1155PresetMinterPauser.json
│           │       ├── ERC1155Receiver.json
│           │       ├── ERC1155Supply.json
│           │       ├── ERC165.json
│           │       ├── ERC165Checker.json
│           │       ├── ERC165Storage.json
│           │       ├── ERC1820Implementer.json
│           │       ├── ERC1967Proxy.json
│           │       ├── ERC1967Upgrade.json
│           │       ├── ERC20.json
│           │       ├── ERC20Burnable.json
│           │       ├── ERC20Capped.json
│           │       ├── ERC20FlashMint.json
│           │       ├── ERC20Pausable.json
│           │       ├── ERC20Permit.json
│           │       ├── ERC20PresetFixedSupply.json
│           │       ├── ERC20PresetMinterPauser.json
│           │       ├── ERC20Snapshot.json
│           │       ├── ERC20Votes.json
│           │       ├── ERC20VotesComp.json
│           │       ├── ERC20Wrapper.json
│           │       ├── ERC2771Context.json
│           │       ├── ERC721.json
│           │       ├── ERC721Burnable.json
│           │       ├── ERC721Enumerable.json
│           │       ├── ERC721Holder.json
│           │       ├── ERC721Pausable.json
│           │       ├── ERC721PresetMinterPauserAutoId.json
│           │       ├── ERC721URIStorage.json
│           │       ├── ERC777.json
│           │       ├── ERC777PresetFixedSupply.json
│           │       ├── EnumerableMap.json
│           │       ├── EnumerableSet.json
│           │       ├── Escrow.json
│           │       ├── Governor.json
│           │       ├── GovernorCompatibilityBravo.json
│           │       ├── GovernorCountingSimple.json
│           │       ├── GovernorProposalThreshold.json
│           │       ├── GovernorSettings.json
│           │       ├── GovernorTimelockCompound.json
│           │       ├── GovernorTimelockControl.json
│           │       ├── GovernorVotes.json
│           │       ├── GovernorVotesComp.json
│           │       ├── GovernorVotesQuorumFraction.json
│           │       ├── IAccessControl.json
│           │       ├── IAccessControlEnumerable.json
│           │       ├── IBeacon.json
│           │       ├── ICompoundTimelock.json
│           │       ├── IERC1155.json
│           │       ├── IERC1155MetadataURI.json
│           │       ├── IERC1155Receiver.json
│           │       ├── IERC1271.json
│           │       ├── IERC1363.json
│           │       ├── IERC1363Receiver.json
│           │       ├── IERC1363Spender.json
│           │       ├── IERC165.json
│           │       ├── IERC1820Implementer.json
│           │       ├── IERC1820Registry.json
│           │       ├── IERC20.json
│           │       ├── IERC20Metadata.json
│           │       ├── IERC20Permit.json
│           │       ├── IERC2612.json
│           │       ├── IERC2981.json
│           │       ├── IERC3156FlashBorrower.json
│           │       ├── IERC3156FlashLender.json
│           │       ├── IERC721.json
│           │       ├── IERC721Enumerable.json
│           │       ├── IERC721Metadata.json
│           │       ├── IERC721Receiver.json
│           │       ├── IERC777.json
│           │       ├── IERC777Recipient.json
│           │       ├── IERC777Sender.json
│           │       ├── IGovernor.json
│           │       ├── IGovernorCompatibilityBravo.json
│           │       ├── IGovernorTimelock.json
│           │       ├── Initializable.json
│           │       ├── Math.json
│           │       ├── MerkleProof.json
│           │       ├── MinimalForwarder.json
│           │       ├── Multicall.json
│           │       ├── Ownable.json
│           │       ├── Pausable.json
│           │       ├── PaymentSplitter.json
│           │       ├── Proxy.json
│           │       ├── ProxyAdmin.json
│           │       ├── PullPayment.json
│           │       ├── ReentrancyGuard.json
│           │       ├── RefundEscrow.json
│           │       ├── SafeCast.json
│           │       ├── SafeERC20.json
│           │       ├── SafeMath.json
│           │       ├── SignatureChecker.json
│           │       ├── SignedSafeMath.json
│           │       ├── StorageSlot.json
│           │       ├── Strings.json
│           │       ├── TimelockController.json
│           │       ├── Timers.json
│           │       ├── TokenTimelock.json
│           │       ├── TransparentUpgradeableProxy.json
│           │       ├── UUPSUpgradeable.json
│           │       ├── UpgradeableBeacon.json
│           │       └── VestingWallet.json
│           ├── finance
│           │   ├── PaymentSplitter.sol
│           │   └── VestingWallet.sol
│           ├── governance
│           │   ├── Governor.sol
│           │   ├── IGovernor.sol
│           │   ├── TimelockController.sol
│           │   ├── compatibility
│           │   │   ├── GovernorCompatibilityBravo.sol
│           │   │   └── IGovernorCompatibilityBravo.sol
│           │   └── extensions
│           │       ├── GovernorCountingSimple.sol
│           │       ├── GovernorProposalThreshold.sol
│           │       ├── GovernorSettings.sol
│           │       ├── GovernorTimelockCompound.sol
│           │       ├── GovernorTimelockControl.sol
│           │       ├── GovernorVotes.sol
│           │       ├── GovernorVotesComp.sol
│           │       ├── GovernorVotesQuorumFraction.sol
│           │       └── IGovernorTimelock.sol
│           ├── interfaces
│           │   ├── IERC1155.sol
│           │   ├── IERC1155MetadataURI.sol
│           │   ├── IERC1155Receiver.sol
│           │   ├── IERC1271.sol
│           │   ├── IERC1363.sol
│           │   ├── IERC1363Receiver.sol
│           │   ├── IERC1363Spender.sol
│           │   ├── IERC165.sol
│           │   ├── IERC1820Implementer.sol
│           │   ├── IERC1820Registry.sol
│           │   ├── IERC20.sol
│           │   ├── IERC20Metadata.sol
│           │   ├── IERC2981.sol
│           │   ├── IERC3156.sol
│           │   ├── IERC3156FlashBorrower.sol
│           │   ├── IERC3156FlashLender.sol
│           │   ├── IERC721.sol
│           │   ├── IERC721Enumerable.sol
│           │   ├── IERC721Metadata.sol
│           │   ├── IERC721Receiver.sol
│           │   ├── IERC777.sol
│           │   ├── IERC777Recipient.sol
│           │   ├── IERC777Sender.sol
│           │   └── draft-IERC2612.sol
│           ├── metatx
│           │   ├── ERC2771Context.sol
│           │   └── MinimalForwarder.sol
│           ├── package.json
│           ├── proxy
│           │   ├── Clones.sol
│           │   ├── ERC1967
│           │   │   ├── ERC1967Proxy.sol
│           │   │   └── ERC1967Upgrade.sol
│           │   ├── Proxy.sol
│           │   ├── beacon
│           │   │   ├── BeaconProxy.sol
│           │   │   ├── IBeacon.sol
│           │   │   └── UpgradeableBeacon.sol
│           │   ├── transparent
│           │   │   ├── ProxyAdmin.sol
│           │   │   └── TransparentUpgradeableProxy.sol
│           │   └── utils
│           │       ├── Initializable.sol
│           │       └── UUPSUpgradeable.sol
│           ├── security
│           │   ├── Pausable.sol
│           │   ├── PullPayment.sol
│           │   └── ReentrancyGuard.sol
│           ├── token
│           │   ├── ERC1155
│           │   │   ├── ERC1155.sol
│           │   │   ├── IERC1155.sol
│           │   │   ├── IERC1155Receiver.sol
│           │   │   ├── extensions
│           │   │   │   ├── ERC1155Burnable.sol
│           │   │   │   ├── ERC1155Pausable.sol
│           │   │   │   ├── ERC1155Supply.sol
│           │   │   │   └── IERC1155MetadataURI.sol
│           │   │   ├── presets
│           │   │   │   └── ERC1155PresetMinterPauser.sol
│           │   │   └── utils
│           │   │       ├── ERC1155Holder.sol
│           │   │       └── ERC1155Receiver.sol
│           │   ├── ERC20
│           │   │   ├── ERC20.sol
│           │   │   ├── IERC20.sol
│           │   │   ├── extensions
│           │   │   │   ├── ERC20Burnable.sol
│           │   │   │   ├── ERC20Capped.sol
│           │   │   │   ├── ERC20FlashMint.sol
│           │   │   │   ├── ERC20Pausable.sol
│           │   │   │   ├── ERC20Snapshot.sol
│           │   │   │   ├── ERC20Votes.sol
│           │   │   │   ├── ERC20VotesComp.sol
│           │   │   │   ├── ERC20Wrapper.sol
│           │   │   │   ├── IERC20Metadata.sol
│           │   │   │   ├── draft-ERC20Permit.sol
│           │   │   │   └── draft-IERC20Permit.sol
│           │   │   ├── presets
│           │   │   │   ├── ERC20PresetFixedSupply.sol
│           │   │   │   └── ERC20PresetMinterPauser.sol
│           │   │   └── utils
│           │   │       ├── SafeERC20.sol
│           │   │       └── TokenTimelock.sol
│           │   ├── ERC721
│           │   │   ├── ERC721.sol
│           │   │   ├── IERC721.sol
│           │   │   ├── IERC721Receiver.sol
│           │   │   ├── extensions
│           │   │   │   ├── ERC721Burnable.sol
│           │   │   │   ├── ERC721Enumerable.sol
│           │   │   │   ├── ERC721Pausable.sol
│           │   │   │   ├── ERC721URIStorage.sol
│           │   │   │   ├── IERC721Enumerable.sol
│           │   │   │   └── IERC721Metadata.sol
│           │   │   ├── presets
│           │   │   │   └── ERC721PresetMinterPauserAutoId.sol
│           │   │   └── utils
│           │   │       └── ERC721Holder.sol
│           │   └── ERC777
│           │       ├── ERC777.sol
│           │       ├── IERC777.sol
│           │       ├── IERC777Recipient.sol
│           │       ├── IERC777Sender.sol
│           │       └── presets
│           │           └── ERC777PresetFixedSupply.sol
│           └── utils
│               ├── Address.sol
│               ├── Arrays.sol
│               ├── Context.sol
│               ├── Counters.sol
│               ├── Create2.sol
│               ├── Multicall.sol
│               ├── StorageSlot.sol
│               ├── Strings.sol
│               ├── Timers.sol
│               ├── cryptography
│               │   ├── ECDSA.sol
│               │   ├── MerkleProof.sol
│               │   ├── SignatureChecker.sol
│               │   └── draft-EIP712.sol
│               ├── escrow
│               │   ├── ConditionalEscrow.sol
│               │   ├── Escrow.sol
│               │   └── RefundEscrow.sol
│               ├── introspection
│               │   ├── ERC165.sol
│               │   ├── ERC165Checker.sol
│               │   ├── ERC165Storage.sol
│               │   ├── ERC1820Implementer.sol
│               │   ├── IERC165.sol
│               │   ├── IERC1820Implementer.sol
│               │   └── IERC1820Registry.sol
│               ├── math
│               │   ├── Math.sol
│               │   ├── SafeCast.sol
│               │   ├── SafeMath.sol
│               │   └── SignedSafeMath.sol
│               └── structs
│                   ├── BitMaps.sol
│                   ├── EnumerableMap.sol
│                   └── EnumerableSet.sol
├── package-lock.json
└── package.json</code></pre><p>오픈재플린에서 제공하고있는 라이브러리는 이렇게 많이 있으며,
<span style='background-color: #fff5b1'> <em>import</em> </span> 를 통해서 사용하고싶은대로 사용하여 개발하면 된다.</p>
<hr>
<p>1) remixd <a href="https://remix-ide.readthedocs.io/en/latest/remixd.html">https://remix-ide.readthedocs.io/en/latest/remixd.html</a>
2) metamask <a href="https://trufflesuite.com/tutorial/index.html#installing-and-configuring-metamask">https://trufflesuite.com/tutorial/index.html#installing-and-configuring-metamask</a>
3) openzeppelin <a href="https://docs.openzeppelin.com/contracts/4.x/#install">https://docs.openzeppelin.com/contracts/4.x/#install</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스마트 컨트랙트와 ERC-20 개발]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/%EC%8A%A4%EB%A7%88%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%9E%99%ED%8A%B8%EC%99%80-ERC-20-%EA%B0%9C%EB%B0%9C</link>
            <guid>https://velog.io/@yonaaaaaaa_a/%EC%8A%A4%EB%A7%88%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%9E%99%ED%8A%B8%EC%99%80-ERC-20-%EA%B0%9C%EB%B0%9C</guid>
            <pubDate>Wed, 19 Jan 2022 07:56:11 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">introduction</h2>
<h4 id="achievement-goals">Achievement Goals</h4>
<ul>
<li>ERC-20과 FT를 이해할 수 있다.</li>
<li>ERC-20에 포함된 함수별 기능을 이해할 수 있다.</li>
<li>ERC-20 스마트 컨트랙트를 테스트넷에 배포할 수 있다.</li>
<li>공개된 ERC-20의 코드를 분석할 수 있다.</li>
<li>ERC-20 개발 환경을 적절히 사용할 수 있다.</li>
<li>Truffle로 ERC-20을 구현할 수 있다.</li>
<li>구현한 ERC-20 스마트 컨트랙트를 Ganache에 배포할 수 있다.</li>
<li>Truffle과 Remix에서 OpenZeppelin 라이브러리를 사용할 수 있다.</li>
<li>클레이튼 개발 환경을 구축할 수 있다.
~~- KaiKas 지갑과 Klaytn IDE를 사용할 수 있다.</li>
<li>클레이튼 기반의 FT를 배포할 수 있다.~~</li>
</ul>
<hr>
<h2 id="⚙️-erc-20">⚙️ ERC-20</h2>
<blockquote>
<h4 id="erc-20이란">ERC-20이란...</h4>
<p>: 2015년 11월 <a href="https://twitter.com/feindura">Faban Vogelsteller</a> 의 <a href="https://eips.ethereum.org/EIPS/eip-20">EIP-20</a> 제안의 의하여 탄생하였으며, ERC-20은 이더리움 토큰에 대한 기준을 정의한 것이다.</p>
</blockquote>
<p>Token Standard 은 아래와 같이 정의된다</p>
<pre><code class="language-javascript">function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)</code></pre>
<h2 id="⚙️-interface">⚙️ Interface</h2>
<p>추상함수 같은 개념이라고 한다. (추상함수: 구현이 이루어지지않고 단지 그 함수의 이름만 가지고 있다는 뜻)</p>
<pre><code class="language-javascript">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); // 유저간 송금</code></pre>
<p>dssd</p>
<pre><code class="language-javascript">interface ERC20Interface {
//...
  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);
}</code></pre>
<p>Transfer 이벤트는 transfer함수가 실행될때마다 로그를 남기고, Approval 이벤트는 approve 함수가 실행 될 때 로그를 남긴다.</p>
<h2 id="⚙️-변수-설정">⚙️ 변수 설정</h2>
<pre><code class="language-javascript">contract SimpleToken is ERC20Interface {
  mapping (address =&gt; uint256) private _balances; // mapping으로 _balances의 msg.sender의 주소의 키값과 uint256의 밸류값을 맵핑(=사용자의 잔고)
  mapping (address =&gt; mapping (address =&gt; uint256)) public _allowances; // 이중mapping으로, [owenr][spender] 의 갯수 (=상환금?)</code></pre>
<pre><code class="language-javascript">  uint256 public _totalSupply; // 총발행량 
  string public _name; // erc-20 토큰 이름
  string public _symbol; // erc-20 토큰 심볼명
  uint8 public _decimals; // 고정 소수점 &#39;decimals = 18&#39; 이 표준이라고함

  constructor(string memory getName, string memory getSymbol) { //구조체
    _name = getName;
    _symbol = getSymbol;
    _decimals = 18;
    _totalSupply = 100000000e18;
    _balances[msg.sender] = _totalSupply;
    }</code></pre>
<h2 id="⚙️-name-함수---토큰-이름">⚙️ name 함수 - 토큰 이름</h2>
<pre><code class="language-javascript">  function name () public view returns (string memory) {
    return _name;
  }</code></pre>
<h2 id="⚙️-sysmbol-함수---토큰-심볼">⚙️ sysmbol 함수 - 토큰 심볼</h2>
<pre><code class="language-javascript">  function symbol() public view returns (string memory) {
    return _symbol;
}</code></pre>
<h2 id="⚙️-decimals-함수---고정-소수점">⚙️ decimals 함수 - 고정 소수점</h2>
<pre><code class="language-javascript">  function decimals() public view returns (uint8) {
    return _decimals;
  }</code></pre>
<h2 id="⚙️-totalsupply-함수---총-발행량">⚙️ totalSupply 함수 - 총 발행량</h2>
<pre><code class="language-javascript">  function totalSupply() external view virtual override returns (uint256) { 
    return _totalSupply;
  }</code></pre>
<p>//  virtual override 에 대해서 검색 해보자</p>
<h2 id="⚙️-balanceof-함수---잔고">⚙️ balanceOf 함수 - 잔고</h2>
<pre><code class="language-javascript">  function balanceOf(address account) external view virtual override returns (uint256) {
    return _balances[account];</code></pre>
<p>// account 계정이 가지고 있는 토큰의 수를 반환</p>
<h2 id="⚙️-transfer-함수---송금">⚙️ transfer 함수 - 송금</h2>
<pre><code class="language-javascript">  function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
    _transfer(msg.sender, recipient, amount); // 내부함수인 _transfer 를 실행시킨다.
    emit Transfer(msg.sender, recipient, amount); // emit: 이벤트 실행을 하는 키워드로 transfer에 대한 이벤트를 발생시킨다.
    return true;
    }</code></pre>
<h2 id="⚙️-approve-함수---승인">⚙️ approve 함수 - 승인</h2>
<pre><code class="language-javascript">  function approve(address spender, uint amount) external virtual override returns (bool) {
    uint256 currentAllownace = _allowances[msg.sender][spender];
    require(currentAllownace &gt;= amount, &quot;ERC20: Transfer amount exceeds allowance&quot;);
    _approve(msg.sender, spender, currentAllownace, amount);
    return true;
    }</code></pre>
<p>Approve는 토큰의 권한을 넘겨주는 함수(성공/실패)
이 함수를 이용할 때는 반드시 Approval 이벤트 함수를 호출해야 한다.</p>
<h2 id="⚙️-allowance-함수---허용">⚙️ allowance 함수 - 허용</h2>
<pre><code class="language-javascript">  function allowance(address owner, address spender) external view override returns (uint256) {
    return _allowances[owner][spender];
    }</code></pre>
<p>허용된 토큰의 개수 (갯수)</p>
<h2 id="⚙️-transferfrom함수---사용자-간-송금">⚙️ transferFrom함수 - 사용자 간 송금</h2>
<pre><code class="language-javascript">  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 &gt;= amount, &quot;ERC20: transfer amount exceeds allowance&quot;);
    _approve(sender, msg.sender, currentAllowance, currentAllowance - amount);
    return true;
  }</code></pre>
<p>해당 토큰의 권한을 이용해 거래를 하도록 만들어 주는 함수(성공/실패)
[msg.sender] 대행자, 생성된 컨트랙트 주소이고 sender 보낸사람이 허락을 해준 만큼만 recipient 받는사람에게 토큰을 이동시킨다.
_transfer 함수 실행 → Transfer 이벤트 실행 → _approve 함수 실행</p>
<hr>
<h2 id="참고-링크">참고 링크</h2>
<p><a href="http://wiki.hash.kr/index.php/ERC-20">- http://wiki.hash.kr/index.php/ERC-20</a>
<a href="https://ethereum.org/en/developers/docs/standards/tokens/erc-20/">- https://ethereum.org/en/developers/docs/standards/tokens/erc-20/</a>
<a href="https://eips.ethereum.org/EIPS/eip-20">- https://eips.ethereum.org/EIPS/eip-20</a>
<a href="https://stackoverflow.com/questions/48219716/what-is-address0-in-solidity">- address(0) 의미, https://stackoverflow.com/questions/48219716/what-is-address0-in-solidity</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Github 명령어 모음집]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Github</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Github</guid>
            <pubDate>Tue, 18 Jan 2022 10:26:35 GMT</pubDate>
            <description><![CDATA[<h2 id="github-명령어-모음집">Github 명령어 모음집</h2>
<h3 id="git-version-확인">git version 확인</h3>
<pre><code class="language-linux">$ git --version</code></pre>
<h3 id="git-config-사용자-변수-설정">git config (사용자 변수 설정)</h3>
<pre><code class="language-linux">$ git config --global -e

$ git config --global user.name &quot;깃허브 username&quot;
$ git config --global user.email &quot;깃허브 e-mail주소&quot;

+ 추가(window와 mac간의 개행문자 차이를 없애주기 위한 설정)
$ git config --global core.autocrlf input 

+ allias 설정(명령어 대체)
$ git config --global alias.qwer &quot;git 명령어&quot;</code></pre>
<h3 id="git-add-스테이징에-올리기">git add (스테이징에 올리기)</h3>
<pre><code class="language-linux">$ git add .</code></pre>
<h4 id="git-rmmv">git rm/mv</h4>
<h3 id="git-status-깃-상태-확인">git status (깃 상태 확인)</h3>
<pre><code class="language-linux">$ git status
$ git status -s</code></pre>
<h4 id="gitignore">.gitignore</h4>
<pre><code class="language-linux">$ echo 파일이름 &gt; .gitignore</code></pre>
<h3 id="git-commit">git commit</h3>
<pre><code class="language-linux">$ git commit -m &quot;커밋 메시지 남기기&quot;</code></pre>
<h4 id="git-commit-메세지-규칙">git commit 메세지 규칙</h4>
<table>
<thead>
<tr>
<th>commit 태그</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>feat</td>
<td>새로운 기능 추가</td>
</tr>
<tr>
<td>fix</td>
<td>버그 수정</td>
</tr>
<tr>
<td>design</td>
<td>css등 사용자 ui 디자인 변경</td>
</tr>
<tr>
<td>!breakingchange</td>
<td>커다란 API 변경</td>
</tr>
<tr>
<td>!hotfix</td>
<td>급한경우, 치명적인 버그를 고쳐야하는 경우</td>
</tr>
<tr>
<td>style</td>
<td>코드 포맷 변경, 세미 콜론 누락, 코드 수정이 없는 경우</td>
</tr>
<tr>
<td>refactor</td>
<td>코드 리팩토링</td>
</tr>
<tr>
<td>comment</td>
<td>필요한 주석 추가 및 변경</td>
</tr>
<tr>
<td>docs</td>
<td>문서를 수정한 경우</td>
</tr>
<tr>
<td>test</td>
<td>테스트 추가, 테스트 리팩토링</td>
</tr>
<tr>
<td>chore</td>
<td>빌드 테스트 업데이트, 패키지 매니저를 설정하는 경우</td>
</tr>
<tr>
<td>rename</td>
<td>파일 혹인 폴더명을 수정하거나 옮기는 작업 만의 경우</td>
</tr>
<tr>
<td>remove</td>
<td>파일 삭제하는 작업</td>
</tr>
<tr>
<td>feat: 어쩌구저쩌구~</td>
<td></td>
</tr>
<tr>
<td>comment: 룰루랄라 신난다 야호~</td>
<td></td>
</tr>
</tbody></table>
<h4 id="version-tag">version tag</h4>
<pre><code class="language-linux">$ git tag v0.0.1 {hash} -am &quot;release&quot;
$ git show v0.0.1

$ git tag -l
$ git tag -d</code></pre>
<p>이런식으로 규칙에 맞게 작성하도록 하자</p>
<h3 id="git-log">git log</h3>
<pre><code>$ git log -p</code></pre><h4 id="git-log-alias-설정">git log alias 설정</h4>
<pre><code>$ git config --global alias.l &quot;log --color --graph --pretty=format:&#39;%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)&lt;%an&gt;%Creset&#39; --abbrev-commit&quot;

$ git l</code></pre><h3 id="git-checkout">git checkout</h3>
<pre><code>$ git checkout 해시값
$ git checkout master</code></pre><h3 id="branch">branch</h3>
<pre><code>$ git checkout -b test v.0.0.2
$ git branch
$ git branch {브런치 네임}  // 브런치 생성
$ git switch {브런치 네임} // 브런치 이동
$ git branch -d {브런치 네임} // 브런치 삭제</code></pre><h3 id="git-merge">git merge</h3>
<pre><code class="language-linux">$(master) git merge {브런치 네임}
$(master) git merge --no-ff {브런치 네임}</code></pre>
<h4 id="conflict">conflict</h4>
<p>다른 브런치에서 하나의 같은 파일을 동시 수정할 때의 merge 오류</p>
<pre><code>// 파일 수정 후
$ git merge --continue</code></pre><h3 id="git-rebase---onto">git rebase --onto</h3>
<hr>
<p>참고) 
[1] git 공식 문서 : [<a href="https://git-scm.com/docs%5D">https://git-scm.com/docs]</a> (<a href="https://git-scm.com/docs">https://git-scm.com/docs</a>)
[2] git log alias : [<a href="https://www.codeit.kr/community/threads/11938%5D">https://www.codeit.kr/community/threads/11938]</a> (<a href="https://www.codeit.kr/community/threads/11938">https://www.codeit.kr/community/threads/11938</a>)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이더리움 EVM과 Solidity - 3]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-EVM%EA%B3%BC-Solidity-3</link>
            <guid>https://velog.io/@yonaaaaaaa_a/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-EVM%EA%B3%BC-Solidity-3</guid>
            <pubDate>Tue, 18 Jan 2022 02:34:31 GMT</pubDate>
            <description><![CDATA[<h2 id="가위바위보-게임-만들기">가위바위보 게임 만들기</h2>
<h3 id="사용자와-게임-구조체-생성">사용자와 게임 구조체 생성</h3>
<h4 id="가위바위보-게임-진행-상황">가위바위보, 게임 진행 상황</h4>
<pre><code class="language-javascript">enum Hand {
  rock, paper, scissors
    }

enum PlayerStatus {
  STATUS_WIN, STATUS_LOSE, STATUS_TIE, STATUS_PENDING
    }

enum GameStatus {
  STATUS_NOT_STARTED, STATUS_STARTED, STATUS_COMPLETE, STATUS_ERROR
    }    </code></pre>
<p>ds</p>
<pre><code class="language-javascript">struct Player {
  address payable addr;
  uint256 playerBetAmount;
  Hand hand;
  PlayerStatus playerStatus;
    }

struct Game {
  Player originator; // 만든사람
  Player taker; // 들어오는사람
  uint256 betAmount;
  GameStatus gameStatus;
    }</code></pre>
<p>dd</p>
<pre><code class="language-javascript">mapping(uint =&gt; Game) rooms;
uint roomLen = 0;

modifier isValidHand (Hand _hand) {
  require((_hand == Hand.rock) || (_hand == Hand.paper) || (_hand == Hand.scissors));
  _;
 }

modifier isPlayer (uint roomNum, address sender) {
  require(sender == rooms[roomNum].originator.addr || sender == rooms[roomNum].taker.addr);
  _;
}
</code></pre>
<h3 id="createroom---게임-생성">CreateRoom - 게임 생성</h3>
<pre><code class="language-javascript">function createRoom (Hand _hand) public payable isValidHand(_hand) returns (uint roomNum) {
  rooms[roomLen] = Game({
    betAmount: msg.value,
    gameStatus: GameStatus.STATUS_NOT_STARTED,
    originator: Player({
      hand: _hand,
      addr: payable(msg.sender),
      playerStatus: PlayerStatus.STATUS_PENDING,
      playerBetAmount: msg.value
      }),
    taker: Player({
      hand: Hand.rock,
      addr: payable(msg.sender),
      playerStatus: PlayerStatus.STATUS_PENDING,
      playerBetAmount: 0
      })
    });
  roomNum = roomLen;
  roomLen = roomLen+1;
  }</code></pre>
<h3 id="joinroom---방-참가">JoinRoom - 방 참가</h3>
<pre><code class="language-javascript">function joinRoom(uint roomNum, Hand _hand) public payable isValidHand( _hand) {
  rooms[roomNum].taker = Player({
    hand: _hand,
    addr: payable(msg.sender),
    playerStatus: PlayerStatus.STATUS_PENDING,
    playerBetAmount: msg.value
    });
  rooms[roomNum].betAmount = rooms[roomNum].betAmount + msg.value;
  compareHands(roomNum);
  }</code></pre>
<h3 id="comparehands---게임-진행">CompareHands - 게임 진행</h3>
<pre><code class="language-javascript">function compareHands(uint roomNum) private {
  uint8 originator = uint8(rooms[roomNum].originator.hand);
  uint8 taker = uint8(rooms[roomNum].taker.hand);

  rooms[roomNum].gameStatus = GameStatus.STATUS_STARTED;

  if(taker == originator) { // 비긴 경우
    rooms[roomNum].originator.playerStatus = PlayerStatus.STATUS_TIE;
    rooms[roomNum].taker.playerStatus = PlayerStatus.STATUS_TIE;
    }
  else if ((taker +1) % 3 == originator) { // 방장이 이긴 경우
    rooms[roomNum].originator.playerStatus = PlayerStatus.STATUS_WIN;
    rooms[roomNum].taker.playerStatus = PlayerStatus.STATUS_LOSE;
    }
  else if ((originator + 1)%3 == taker){  // 참가자가 이긴 경우
    rooms[roomNum].originator.playerStatus = PlayerStatus.STATUS_LOSE;
    rooms[roomNum].taker.playerStatus = PlayerStatus.STATUS_WIN;
    }
  else {  // 그 외의 상황에는 게임 상태를 에러로 업데이트한다
    rooms[roomNum].gameStatus = GameStatus.STATUS_ERROR;
    }
  }</code></pre>
<h3 id="payout---베팅-금액-송금">Payout - 베팅 금액 송금</h3>
<pre><code class="language-javascript">function payout(uint roomNum) public payable isPlayer(roomNum, msg.sender) {
  if (rooms[roomNum].originator.playerStatus == PlayerStatus.STATUS_TIE 
      &amp;&amp; rooms[roomNum].taker.playerStatus == PlayerStatus.STATUS_TIE) {
    rooms[roomNum].originator.addr.transfer(rooms[roomNum].originator.playerBetAmount);
    rooms[roomNum].taker.addr.transfer(rooms[roomNum].taker.playerBetAmount);
    }
  else {
    if (rooms[roomNum].originator.playerStatus == PlayerStatus.STATUS_WIN) {
      rooms[roomNum].originator.addr.transfer(rooms[roomNum].betAmount);
      } 
    else if (rooms[roomNum].taker.playerStatus == PlayerStatus.STATUS_WIN) {
      rooms[roomNum].taker.addr.transfer(rooms[roomNum].betAmount);
      } 
    else {
      rooms[roomNum].originator.addr.transfer(rooms[roomNum].originator.playerBetAmount);
      rooms[roomNum].taker.addr.transfer(rooms[roomNum].taker.playerBetAmount);
      }
    }
  rooms[roomNum].gameStatus = GameStatus.STATUS_COMPLETE; // 게임이 종료되었으므로 게임 상태 변경
  }</code></pre>
<hr>
<p>어렵다...😭😭😭😭😭</p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/f0a49c38-10e0-4241-8b62-6d7c1f571a25/image.png" alt="">
가위바위보에서 내가 무엇을 냈는지 보여지면 안된다... public 말고 private 로 하면 되지않을까 싶다..?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이더리움 EVM과 Solidity - 2 ]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-EVM%EA%B3%BC-Solidity-2</link>
            <guid>https://velog.io/@yonaaaaaaa_a/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-EVM%EA%B3%BC-Solidity-2</guid>
            <pubDate>Mon, 17 Jan 2022 08:27:59 GMT</pubDate>
            <description><![CDATA[<p>이유는 모르겠는데 이전에 썻던 글이 비공개로 전환이 된다..😭😭😭😭</p>
<h2 id="🔨-solidity">🔨 Solidity</h2>
<h3 id="📔-솔리디티-기본-문법">📔 솔리디티 기본 문법</h3>
<h3 id="📔-함수">📔 함수</h3>
<pre><code class="language-javascript">function 함수이름(파라미터 형식1, 파라미터1, ...) {...}
or
function 함수이름(파라미터,...) returns (반환 형식) {...}</code></pre>
<p>함수 접근 수준</p>
<ul>
<li>external : 외부 컨트랙트나 클라이언트 코드에서 호출할 수는 있으나, 컨트랙트 내부에서는 호출 X</li>
<li>public(default) : 컨트랙트 내부, 외부 컨트랙트, 클라이언트 코드에서 호출 가능</li>
<li>internal : 컨트랙트 멤버와 상속된 컨트랙트에서만 호출 가능</li>
<li>private : 컨트랙트 멤버만 호출 가능</li>
</ul>
<pre><code class="language-javascript">contract exmaple {
  function changeName(address account, string newName) internal {...}
  function checkGas(uint256 account) private returns (bool) {...}</code></pre>
<h4 id="view-pure">view, pure</h4>
<p>view 로 표시된 함수는 상태를 변경하지 않는 읽기 전용 함수.
pure 는 스토리지에서 변수를 읽거나 쓰지 않는 함수.</p>
<pre><code class="language-javascript">function checkGas(uint256 amount) private pure returns (bool) { ... }
or
function validateAccount(address account) internal view returns (bool) { ... }</code></pre>
<h4 id="payable">payable</h4>
<p>payable을 선언하면 함수에서 이더를 받을 수 있다.</p>
<pre><code class="language-javascript">function getEther() payable returns (bool) {
  if (msg.value === quoteFee) {
    // ...
  }
}</code></pre>
<h4 id="생성자-함수constructor">생성자 함수(constructor)</h4>
<p>컨트랙트가 생성될 때, 생성자 함수가 실행되며 컨트랙트의 상태를 초기화 할 수 있다.</p>
<pre><code class="language-javascript">address public account;

consturctor(address _account) internal {
  account = _account
}</code></pre>
<h4 id="selfdestruct">selfdestruct</h4>
<p>컨트랙트 소멸</p>
<pre><code class="language-javascript">selfdestruct(컨트랙트 생성자의 주소);</code></pre>
<h3 id="📔-함수-변경자modifier">📔 함수 변경자(modifier)</h3>
<p>함수 선언에 <span style='background: #f5f0ff'> modifier </span> 를 추가하여 함수를 실행하기 전, 요구 조건을 만족하는지 확인한다.
<span style='background: #f5f0ff'> _; </span> 을 사용하여 함수 변경자를 구분할 수 있다.</p>
<pre><code class="language-javascript">int public num = 0;
modifier changeNum {
  num++; // 함수 실행 전 실행
  _; // 함수 실행
  num--; // 함수 실행 후 실행

function func() public changeNum {
  if(num == 1) {
    // do something...
  }
}</code></pre>
<h3 id="📔-상속">📔 상속</h3>
<p>상속을 사용하려면 부모 컨트랙트에 <span style='background: #f5f0ff'>is</span> 키워드를 지정해준다.</p>
<pre><code class="language-javascript">contract Child is Parent {...}
or
contract Child is Parent, Parent2,, {...}</code></pre>
<h3 id="📔-에러-핸들링">📔 에러 핸들링</h3>
<ul>
<li><span style='background: #f5f0ff'>revert</span> : 해당 함수를 종료하고 에러 리턴<pre><code class="language-javascript">if (amount &gt; msg.value / 2 ether) 
revert(&quot;Not enough Ether provided.&quot;);</code></pre>
</li>
<li><span style='background: #f5f0ff'>require</span>, <span style='background: #f5f0ff'>assert</span> : 설정한 조건이 참인지 확인하고, 조건이 거짓이면 에러 리턴
assert는 사용법은 동일하나, 사용하지 않은 가스를 호출자에게 반환하지 않고 공급된 가스를 모두 소모하여 상태를 원래대로 되돌린다.<pre><code class="language-javascript">reuire(
amount &lt;= msg.value / 2 ether, // 조건이 참이면 패스, 거짓이면 출력
&quot;Not enough Ether provided.&quot;
);
</code></pre>
</li>
</ul>
<p>// 송금 진행</p>
<pre><code>
### 📔 열거형
``` javascript
enum EvalLevel {Bad, Soso, Great}

EvalLevel kimcoding = EvalLevel.Bad

int16 kimcodingValue = int16(kimcoding); // kimcoding 열거형 값 0을 정수형으로 변환            </code></pre><h3 id="📔-이벤트">📔 이벤트</h3>
<p><span style='background: #f5f0ff'>event</span> 또는 <span style='background: #f5f0ff'>emit</span> 사용</p>
<pre><code class="language-javascript">event Transfer(address from, address to, uint256 value); 

function transfer(address to, address amount) {
  //...

  emit Transfer(msg.sender, to, amount);
}
</code></pre>
<h2 id="가위바위보-게임-만들어보기">가위바위보 게임 만들어보기</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[지갑의 사용과 지갑 개발]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/%EC%A7%80%EA%B0%91%EC%9D%98-%EC%82%AC%EC%9A%A9%EA%B3%BC-%EC%A7%80%EA%B0%91-%EA%B0%9C%EB%B0%9C</link>
            <guid>https://velog.io/@yonaaaaaaa_a/%EC%A7%80%EA%B0%91%EC%9D%98-%EC%82%AC%EC%9A%A9%EA%B3%BC-%EC%A7%80%EA%B0%91-%EA%B0%9C%EB%B0%9C</guid>
            <pubDate>Fri, 14 Jan 2022 05:59:00 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">Introduction</h2>
<h4 id="achievement-goals">Achievement Goals</h4>
<ul>
<li>지갑의 종류를 설명할 수 있다.</li>
<li>이더리움 또는 클레이튼 기반의 지갑을 구분할 수 있다.</li>
<li>메타마스크 지갑에서 네트워크를 변경할 수 있다.</li>
<li>마이이더월렛을 사용할 수 있다.</li>
<li>하드월렛을 연동할 수 있다.</li>
<li>리눅스 CLI를 통해 지갑과 키를 관리하고, 사용할 수 있다.</li>
<li>HD 월렛과 니모닉 월렛을 이해할 수 있다.</li>
<li>니모닉 코드를 이용하여 니모닉 월렛을 개발할 수 있다.</li>
<li>니모닉 월렛과 HD 월렛의 차이를 이해할 수 있다.</li>
</ul>
<hr>
<h2 id="지갑의-종류">지갑의 종류</h2>
<h3 id="지갑의-종류-알아보기">지갑의 종류 알아보기</h3>
<p>지난 블록체인 이론에서 나왔던 내용이지만 한번 더 상기시키고 가면 좋을 것 같다.
스마트컨트랙트 지갑(metamask), 하드웨어 지갑(ledger), 모바일 지갑(어플버전), 데스크탑 지갑(응용프로그램버전), 웹 지갑 등이 있다.
거래소에서 사용하는 콜드월렛과 핫월렛의 차이점도 알고 넘어가자.
💡다중 암호화폐 지원을 하는 지갑도 있고, 카드처럼 되어있는 지갑도 있고, 지문인증형 하드웨어 지갑은 국내 최고 블록체인 지갑 회사인 <a href="0xd9Eba49d7A8073A779633a838e18589f4edBFe22">디센트</a>가 있다.</p>
<h3 id="메타마스크">메타마스크</h3>
<p><a href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=ko">메타마스크 확장프로그램 다운로드 링크</a>
확장프로그램 추가한 다음에 시작하기를 눌러 지갑생성을 진행하면 누구나 쉽게 지갑을 만들 수 있다.
만드는 과정에서 비밀 백업 구문(Secret Recovery Phrase)이 나오는데 이것이 니모닉 키(개인 키)이다.</p>
<p>⚠️<span style='color:red'> <strong>반드시 잃어버리지말고 누구한테도 알려줘서는 안되니 잘 보관하도록 해라</strong> </span>⚠️</p>
<h4 id="개발환경을-위한-테스트넷-네트워크-설정하기---ropsten">개발환경을 위한 테스트넷 네트워크 설정하기 - Ropsten</h4>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/25152563-3575-4736-9fb8-5b0890cc057e/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/f11033e4-0d6e-4e8c-a20e-a393e7dd2559/image.png" alt="이러면 됨?"></p>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/c8b37e57-0e0a-48e7-9b19-e85259498a37/image.png" alt="왜 안됨?">
보통은 첫번째 사진처럼 나올건데, 만약 테스트 네트워크가 안보인다 싶으면
메타마스크 오른쪽 상단에 보이는 프로필 클릭 &gt; [설정] &gt; [고급] &gt; Show test networks 기능 활성화 해주면 된다.</p>
<p>우리는 Ropsten 이라는 테스트넷을 사용할것이다. (<a href="https://ethereum.stackexchange.com/questions/27048/comparison-of-the-different-testnets/30072#30072">테스트넷의 차이점이 궁금하다면?? - 링크</a>)</p>
<h4 id="테스트용-이더리움-수령하기">테스트용 이더리움 수령하기</h4>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/267eb028-6999-4d14-a93e-7c7e756ad836/image.png" alt="">
Account 밑에 보이는 0x로 시작하는 주소가 본인의 지갑 주소이다. 딱히 기억할 필요는 없고, 공개 키이기 때문에 숨길 필요도 없다. 여튼 지갑 주소를 복사하였으면 <a href="https://faucet.ropsten.be/">Ropsten Ethereum Faucet</a> 에 접속해서 테스트용 이더리움을 받도록하자. (30초정도 걸렸고, 0.3이더를 받았다)</p>
<h3 id="마이이더월렛">마이이더월렛</h3>
<p><a href="https://www.myetherwallet.com/">마이이더월렛...</a> 이더리움 전용 암호화폐 지갑이다. 메타마스크가 활발하게 사용되기 이전에는 많이쓰였는데 요즘에는 잘 사용되지않는것같다. (그러므로 만드는 방법은 생략하겠다...)</p>
<h3 id="geth-wallet">Geth Wallet</h3>
<p>웹 말고도 CLI를 통해서도 계정을 생성하고, 네트워크 설정하는 기능 모두 사용가능하다.
<code>$ sudo add-apt-repository -y ppa:ethereum/ethereum</code></p>
<p><code>$ sudo apt-get update</code>
<code>$ sudo apt-get install ethereum</code></p>
<p><code>$ geth -h</code> 를 통해서 geth 관련 명령어가 어떤 것이 있는지 확인 해보록...</p>
<h4 id="mew-gethcli-메타마스크로-생성된-지갑의-차이점">MEW, Geth(CLI), 메타마스크로 생성된 지갑의 차이점</h4>
<p>구조의 순서가 다르다.</p>
<hr>
<h2 id="지갑-개발">지갑 개발</h2>
<h3 id="니모닉과-hd-wallet-이해하기">니모닉과 HD Wallet 이해하기</h3>
<p>니모닉과 HD Wallet 또한 블록체인 이론에서 한번 봐왔던 내용이니 어떠한 개념이었는지 상기하고 넘어가자
HD Wallet 은 계층적 결정적 지갑의 약자로 하나의 Seed값(니모닉 키)으로 여러 개의 주소(Account)를 생성 할수있는 지갑이다.
지갑과 관련해서는 니모닉 단어를 생성하는 <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">BIP-39</a> 와 계정과 주소를 생성하기 위한 <a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP-44</a> 를 자주 접하게 된다.</p>
<p>BIP-44는 미리 정의된 다섯 가지의 트리 레벨로 구성된 구조를 갖는다.
<code>m / purpose&#39; / coin_type&#39; / account&#39; / change / address_index</code></p>
<ul>
<li><p>purpose&#39; : 목적은 항상 44로 설정한다.</p>
</li>
<li><p>coin_type&#39; : 암호화폐의 유형을 지정한다. (<a href="https://github.com/satoshilabs/slips/blob/master/slip-0044.md">SLIP0044</a> 라는 문서에 여러화폐가 정의되어있다)
💡 모든 화폐의 테스트넷은 <strong>1번</strong>으로 m/44&#39;/1&#39; 이라 표기하면 된다 💡
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/7e332c0b-1a80-492a-a4ed-3a3653fdd006/image.png" alt="">
분명 해시넷에서는 61이라고 나와있는데... SLIP-0044를 보니 모든 테스트넷은 1번인 것이다..
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/d5c335e8-a9b8-457b-9686-ca2800ba0a1f/image.png" alt="">
그래서 낼름 바꿨다...ㅋㄷㅋㄷ (찾아보니깐 예전에는 61 이었다고 한다 - <a href="https://github.com/LedgerHQ/app-ethereum/issues/2">링크</a>)</p>
</li>
<li><p>account&#39; : 계정이다.
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/96213699-d1c0-4ed2-adb6-6779af1e033a/image.png" alt="">
이런식으로 나는 m/44&#39;/8217&#39;/0&#39; 과 m/44&#39;/8217&#39;/1&#39; 의 계정을 갖고있다는 의미로 받아들임 될 듯하다.</p>
</li>
<li><p>change : 잔돈 계정 여부.</p>
</li>
<li><p>address_index : 사용 가능한 주소 인덱스.</p>
</li>
</ul>
<p>change와 address_index는 이해가 좀 안되서 그냥 해시넷꺼 가져왔다. 혹시나 저 글을 보고 이해되면 댓글로 알려달라.</p>
<pre><code>레벨-4 (change, 잔돈 계정 여부) : 트리의 네번째 레벨은 잔돈 계정 여부(change)이다. BIP44는 원래 비트코인을 위해 제작되었기 때문에 이더리움 세계와 관련이 없는 &#39;특이점&#39;(quirk)이 포함되었다. HD 지갑에는 2개의 하위 트리가 있는데 하나는 입금 주소 작성용이고 다른 하나는 잔액 주소 작성용이다. 이더리움은 비트코인에 있는 잔액 주소가 필요 없으므로 단지 &#39;입금&#39; 경로만 사용하여 항상 0이다. 이전 레벨은 강화파생만 사용했지만 이 레벨은 비보안 환경에서 사용할 수 있도록 확장된 공개키를 트리의 계정 수준에서 내보낼 수 있게 하기 위해서 일반 파생을 사용한다. [1]
레벨-5 (address_index, 사용 가능한 주소 인덱스) :트리의 다섯번째 레벨은 사용 가능한 주소 인덱스로 만드는 것이다. 예를 들어 주 메인 계정에서 이더리움 지급을 위한 세 번째 입금 주소는 M/44&#39;/60&#39;/0&#39;/0/2가 될 것이다.[2] 이것은 HD 지갑에서 파생된 level-4의 자식이다.</code></pre><p>이해를 돕는 예제를 통해 읽으면서 한번 더 복습해보자</p>
<pre><code class="language-javascript">M/44&#39;/60&#39;/0&#39;/0/2 : 메인 이더리움 계정에 대한 세 번째 수신 공개키
M/44&#39;/0&#39;/3&#39;/1/14 : 4번째 비트코인 계정의 15번째 주소 변경 공개키 
m/44&#39;/2&#39;/0&#39;/0/1 : 트랜잭션 서명을 위한 라이트코인 메인 계정의 두 번째 개인 키</code></pre>
<h3 id="니모닉-월렛-개발하기">니모닉 월렛 개발하기</h3>
<p>eth-lightwallet 에 대해서 학습해보자 (<a href="https://www.npmjs.com/package/eth-lightwallet">eth-lightwallet</a>)</p>
<hr>
<h2 id="참고자료">참고자료</h2>
<ul>
<li><input disabled="" type="checkbox"> ㅋㅋㅋ</li>
<li><a href="https://wiki.trezor.io/Cryptocurrency_standards#BIP43_-_Purpose_field_for_deterministic_wallets">https://wiki.trezor.io/Cryptocurrency_standards#BIP43_-_Purpose_field_for_deterministic_wallets</a></li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[블록체인 개념 정리]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@yonaaaaaaa_a/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 10 Jan 2022 11:36:14 GMT</pubDate>
            <description><![CDATA[<h2 id="용어-정리">용어 정리</h2>
<p>천천히 쓸것..</p>
<h2 id="개인적인-생각">개인적인 생각</h2>
<h3 id="블록체인을-공부하게-된-이유">블록체인을 공부하게 된 이유</h3>
<p>재미있어보였다.</p>
<h3 id="비트코인-1억-갈까요">비트코인 1억 갈까요??</h3>
<p>갈수도있고 안갈수도있다.
나또한 코인에서 가즈아~!!! 를 외치고 열광했을때가 있었다.
그때는 분명 비트코인이 대단하고 완벽하고 미래의 화폐라고 생각한적이 있었다.
근데 지금은 다르다.</p>
<p>탈중앙화가 무조건적으로 좋은것은 아니다.
때때로 중앙화가 필요할 때도 있다고 생각한다.</p>
<h3 id="블록체인-공부-어떻게-시작하는게-좋을까요">블록체인 공부 어떻게 시작하는게 좋을까요?</h3>
<p>블록체인 업계에는 생각보다 여러 분야의 사람들이 많이 존재한다.
또한 개발자 뿐만 아니라 분석가, 디자이너, 변호사 등등 심지어 하나의 생태계에서 철학, 세계관도 굉장히 중요하다.</p>
<p>확실한 건,,, 이런 이론을 읽어보는 것 보다 직접 한번 해보는것이 큰 도움이 될 것이다.</p>
<h2 id="앞으로의-목표">앞으로의 목표</h2>
<p>비밀이다🤫</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Defi]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/Defi</link>
            <guid>https://velog.io/@yonaaaaaaa_a/Defi</guid>
            <pubDate>Mon, 10 Jan 2022 11:27:10 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Defi 관련 용어 파트이다.</p>
<h3 id="defi">Defi</h3>
<p>탈중앙화 금융</p>
<h3 id="dao">DAO</h3>
<p>커뮤니티</p>
<h3 id="ico">ICO</h3>
<p>코인을 이용한 자금조달</p>
<h3 id="ieo">IEO</h3>
<p>거래소 코인</p>
<h3 id="dex">DEX</h3>
<p>탈중앙화 거래소</p>
<h3 id="sto">STO</h3>
<p>증권형 토큰</p>
<h3 id="풀투게더">풀투게더</h3>
<p>?</p>
<h3 id="스테이킹staking-pos--dpos">스테이킹(Staking) /PoS / DPoS</h3>
<p>코인을 지분으로 맡기고 보상으로 코인을 받는 시스템 </p>
<h3 id="스테이블코인">스테이블코인</h3>
<p>1달러 = 1ust 같은 가격변동성이 적은 안정화된 코인 (일반 스테이블, 담보기반 스테이블, 알고리즘기반 스테이블이 존재한다)</p>
<h3 id="테더">테더</h3>
<p>달러를 1:1 교환하여 테더사에서 발행하는 스테이블코인</p>
<h3 id="메이커다오와-다이dai">메이커다오와 다이(DAI)</h3>
<p>메이커다오를 담보로 맡기고 다이(DAI)라는 스테이블 코인을 받는다</p>
<h3 id="토큰화된-비트코인">토큰화된 비트코인</h3>
<p>wbtc(Wrapped Bitcoin)</p>
<h3 id="이자농사yield-farming">이자농사(Yield Farming)</h3>
<p>유동성 공급을한 댓가로 토큰을 받는 Defi 시스템</p>
<h3 id="다크-풀dark-pool">다크 풀(Dark Pool)</h3>
<h3 id="유동성-풀liquidity-pool">유동성 풀(Liquidity Pool)</h3>
<h3 id="자동화된-시장-메이커amm">자동화된 시장 메이커(AMM)</h3>
<h3 id="비영구적-손실">비영구적 손실</h3>
<h3 id="컴파운드comp">컴파운드(COMP)</h3>
<h3 id="에이브aave">에이브(AAVE)</h3>
<h3 id="유니스왑uni">유니스왑(UNI)</h3>
<h3 id="스시스왑sushi">스시스왑(SUSHI)</h3>
<h3 id="베이커리스왑">베이커리스왑</h3>
<h3 id="버거스왑">버거스왑</h3>
<h3 id="커브파이낸스">커브파이낸스</h3>
<h3 id="연파이낸스yfi">연파이낸스(YFI)</h3>
<h3 id="알파호모라">알파호모라</h3>
<h3 id="플래시론">플래시론</h3>
<h3 id="탄력적-공급-토큰">탄력적 공급 토큰</h3>
<h3 id="비트코인-etf">비트코인 etf</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[DApp]]></title>
            <link>https://velog.io/@yonaaaaaaa_a/DApp</link>
            <guid>https://velog.io/@yonaaaaaaa_a/DApp</guid>
            <pubDate>Mon, 10 Jan 2022 11:26:16 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">Introduction</h2>
<h4 id="achievement-goals">Achievement Goals</h4>
<ul>
<li>DApp의 정의를 설명할 수 있다.</li>
<li>스마트 컨트랙트 기반의 DApp을 이해할 수 있다.</li>
<li>DApp을 예시(DEX, DeFi, NFT, Game 등)와 함께 설명할 수 있다.</li>
<li>거래소와 DApp의 연관관계를 이해할 수 있다.</li>
<li>써드파티와 DApp의 연관관계를 이해할 수 있다.</li>
<li>Saved Data 기반 DApp을 설명할 수 있다.</li>
<li>생태계의 구성 레벨이 따른 DApp 탈중앙화 레벨을 이해할 수 있다.</li>
<li>국내 실제 사용 사례를 설명할 수 있다.</li>
<li>해외 실제 사용 사례를 설명할 수 있다.</li>
<li>DApp의 문제점이 무엇인지 이해할 수 있다.<h2 id="dapp">DApp</h2>
<blockquote>
<p>💡탈중앙화 분산 애플리케이션(Decentralized Application, DApp) : 플랫폼 코인 위에서 작동하는 토큰(token)</p>
</blockquote>
</li>
</ul>
<p><img src="https://images.velog.io/images/yonaaaaaaa_a/post/e0bdb40c-bc56-4232-bde5-463e67cdd66c/image.png" alt="">
위와 같이 많은 플랫폼 코인들이 존재하고 2022년 1월 11일 기준 DApp의 개수는 약 3800개 정도 있다고 한다. 그 중 이더리움이 2900개, eos가 300개, bsc가 130개이지만 이더리움을 제외하고 개발이 저조한 편이었다. (통계 자료는 <a href="https://www.stateofthedapps.com/ko/stats/platform/tron#new">링크</a> 여기서 확인해보았다)</p>
<h4 id="dapp의-특징">DApp의 특징</h4>
<ol>
<li>탈중앙화</li>
<li>위·변조 불가</li>
<li>가독성</li>
<li>토큰 이코노미<h4 id="dapp의-조건-링크">DApp의 조건 (<a href="https://github.com/DavidJohnstonCEO/DecentralizedApplications#table-of-contents">링크</a>)</h4>
</li>
<li>완전한 오픈 소스 </li>
<li>데이터와 작동 기록은 중앙의 장애 지점을 피하기 위해 공개된 분산 블록체인에 암호화 방식으로 저장해야 한다</li>
<li>애플리케이션에 액세스하는 데 필요한 암호화 토큰(비트코인 또는 시스템 고유의 토큰)을 사용해야 하며 (광부/농부)의 가치 기여는 애플리케이션의 토큰으로 보상되어야 한다</li>
<li>노드가 DApp에 기여하고 있는 가치의 증거 역할을 하는 표준 암호 알고리즘이 있어야 한다</li>
</ol>
<h3 id="스마트-컨트랙트-기반의-dapp">스마트 컨트랙트 기반의 DApp</h3>
<blockquote>
<p>💡탈중앙화 거래소(Decentralized Exchange, DEX) : P2P방식으로 운영되는 탈중앙화된 암호화폐 거래소
💬 추가로 현재 바이낸스(binance) 또는 업비트(Upbit) 같은 암호화폐를 거래할 수 있는 거래소는 중앙화 거래소를 CEX 라고 한다.</p>
</blockquote>
<h4 id="dex의-특징">DEX의 특징</h4>
<ul>
<li>중개자 없이 토큰/암호화 자산의 P2P 교환한다</li>
<li>참가자는 자신의 자산(개인 키)를 제어한다</li>
<li>모든 거래는 블록체인에 기록되며 누구나 볼수있다(투명성)</li>
<li>확인 후 모든 거래는 취소 또는 수정이 불가능하다</li>
</ul>
<blockquote>
<p>💡탈중앙화 금융(Decentralized Finance, Defi) : 암호화폐를 담보로 걸고 일정 금액을 대출 받거나, 혹은 다른 담보를 제공하고 암호화폐를 대출 받는 방식 (<em>borrow, lending</em>)</p>
</blockquote>
<h4 id="defi의-특징">Defi의 특징</h4>
<ul>
<li>중개자가 필요 없다</li>
<li>송금 수수료가 저렴하다 (이더리움은 비싸던데...?)</li>
<li>기존 유동화가 불가능하던 실물자산도 토큰화 과정을 거치면 매매가 가능하다 (NFT)</li>
</ul>
<blockquote>
<p>💡대체 불가능한 토큰(Non Fungible Token) : 디지털 파일과 구매자의 정보를 블록체인으로 기록해 파일을 디지털 자산으로 바꾸는 기술 (<em>erc-721, erc-1155</em>)</p>
</blockquote>
<p>최근들어 NFT와 토큰을 활용하여 블록체인 기반 게임들의 개발이 이루어지고있다 (P2E)
NFT를 담보로 맡기고 대출을 받는 시스템도 나오고있는 것 같다</p>
<h3 id="saved-data-기반의-dapp">Saved Data 기반의 DApp</h3>
<p>Saved Data 기반의 DApp의 특징은 기록된 데이터를 수정할 수 없다는 것이고 아래와 같은 용도로 활용된다.</p>
<ul>
<li>sns</li>
<li>물류</li>
<li>storage</li>
<li>NFT<h2 id="dapp-vs-app">DApp vs App</h2>
<h3 id="dapp과-전통적인-앱의-차이">DApp과 전통적인 앱의 차이</h3>
<table>
<thead>
<tr>
<th align="center">구분</th>
<th align="center">DApp</th>
<th align="center">APP</th>
</tr>
</thead>
<tbody><tr>
<td align="center">가동성</td>
<td align="center">분산 원장 기술을 사용하기 때문에 노드가 전체 꺼지지 않는 이상 앱 사용하는데 큰 문제 없음</td>
<td align="center">중앙화된 서버가 문제가 발생하면 앱 사용이 불가능</td>
</tr>
<tr>
<td align="center">구동방식</td>
<td align="center">스마트 컨트랙트</td>
<td align="center">서버-앱 프로그래밍에 따라</td>
</tr>
<tr>
<td align="center">보안</td>
<td align="center">좋음</td>
<td align="center">해킹의 위험이 높음</td>
</tr>
<tr>
<td align="center">데이터 삭제 여부</td>
<td align="center">불가능</td>
<td align="center">가능</td>
</tr>
<tr>
<td align="center">투명성</td>
<td align="center">누구나 볼수 있음</td>
<td align="center">권한이 있는 사람만 접근·제어 가능</td>
</tr>
<tr>
<td align="center">거래 속도</td>
<td align="center">블록체인마다 차이가 있지만 트랜잭션이 몰릴경우 느림</td>
<td align="center">보통 빠른편</td>
</tr>
<tr>
<td align="center">DApp의 가장 큰 특징은 탈중앙화이고 메인넷에서 한번 실행되면 절대 변경이 안된다는 점이다...</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">### DApp 탈중앙화 레벨</td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
<li>합의 알고리즘에 따른 탈중앙화</li>
<li>거버넌스의 탈중앙화(DAO)</li>
<li>Defi 에서의 탈중앙화<h2 id="dapp-사례">DApp 사례</h2>
<h3 id="국내-사례">국내 사례</h3>
<blockquote>
<p>💡블록체인 기반 신원증명 기술(Decentralized Identifier, DID) : 개개인이 자신의 정보에 완전한 통제권을 가질 수 있게 하는 기술</p>
</blockquote>
</li>
</ul>
<p><a href="http://wiki.hash.kr/index.php/%EC%95%84%EC%9D%B4%EC%BD%98%EB%A3%A8%ED%94%84">아이콘루프</a></p>
<h3 id="해외-사례">해외 사례</h3>
<p><a href="https://pancakeswap.finance/">DEX - 팬케이크스왑</a>
<a href="https://uniswap.org/">DEX - 유니스왑</a>
<a href="https://dydx.exchange/">DEX - DYDX</a></p>
<p><a href="https://boredapeyachtclub.com/#/">NFT - BAYC</a>
<a href="https://www.larvalabs.com/cryptopunks">NFT - Cryptopunks</a></p>
<p><a href="https://yieldguild.io/">DAO - ygg</a></p>
<p><a href="https://axieinfinity.com/">GAME - Axieinfinity</a>
<a href="https://www.sandbox.game/kr/">GAME - 샌드박스 </a></p>
<h2 id="dapp-방향성">DApp 방향성</h2>
<h3 id="dapp의-문제점">DApp의 문제점</h3>
<ul>
<li>느린 속도와 이용에 따른 비용 문제 
→ 프로젝트에 따라 다른 경우가 있지만 이더리움은 기본적으로 수수료도 비싼편이고, 트랜잭션이 몰릴 경우 속도가 느리다. 그에 반면 솔라나(Solana) 또는 bsc(바이낸스 스마트체인)은 빠른 tps와 수수료도 굉장히 싼 편이다. 블록체인이 성장함에 따라 속도·비용 문제는 점차 해결될 것이라고 생각한다</li>
<li>사용자 편의성 문제
→ 아직까지 블록체인 기술이 보편적이지 않아서 어렵다고 생각하는 사람들이 많다. 이또한 블록체인이 성장하면서 자연스럽게 해결될 것이라고 생각한다. 그리고 프로젝트를 진행함에 앞써 ui/ux를 사용자친화적이게 개발하는 것 또한 굉장히 중요하다고 생각한다.</li>
<li>암호화폐의 가격 변동성
→ 비트코인을 비롯하여 가격변동성이 있으면 화폐로 쓰이기 모호할 것이다. 그리하여 가격변동성이 없는 스테이블코인들이 등장하였으며 점차적으로 확대되고 있다.</li>
<li>규제
→ <a href="https://news.naver.com/main/read.naver?mode=LSD&amp;mid=sec&amp;sid1=105&amp;oid=417&amp;aid=0000766981">국내에서 퇴출되어버린 P2E</a>
→ <a href="https://www.bbc.com/korean/international-58479624">비트코인을 법정화폐로 채택한 나라, 엘살바도르</a><h3 id="dapp의-전망">DApp의 전망</h3>
<img src="https://images.velog.io/images/yonaaaaaaa_a/post/26a98555-a2cb-402e-b10e-0f517babfc15/image.png" alt="">
지금까지 &quot;scam&quot; 이라고 불렸던 것들이지만 현재 가격을 보면 막상 그렇지 않다. 최근 Web3.0, Metaverse, gameFi 등등 스캠이다 라고 불리우는것들이 몇년뒤에는 어떻게 활용되고 있을지 너무 기대가 되고 발 빠르게 변화하는 이런 기술력을 이해하고 공부할 수 있다는 것을 가까이서 접할수있다는것이 블록체인의 매력이 아닐까 싶다... </li>
</ul>
<hr>
<h2 id="핵심요약---question">핵심요약 - Question</h2>
<h3 id="🐚-dapp이-무엇인가요">🐚 dApp이 무엇인가요?</h3>
<pre><code>DAPP이란 탈중앙화 어플리케이션으로, 블록체인 플랫폼 위에서 동작하는 모든 토큰들을 말한다 (erc-20)</code></pre><h3 id="🐚-dex--de-fi--nft-가-무엇인가요">🐚 DEX / De-Fi / NFT 가 무엇인가요?</h3>
<pre><code>DEX는 탈중앙화 거래소이며, 
Defi는 탈중앙화 금융시스템으로, 암호화폐를 담보로 대출 또는 예금을 받는 시스템을 뜻한다. 
NFT는 대체 불가 토큰으로, 디지털 파일과 거래기록을 블록체인 기술을 이용하여 디지털 자산으로 바꾸는 기술이다.
(erc-721, erc-1155)</code></pre><h3 id="🐚-uniswap과-sushiswap의-차이점은">🐚 Uniswap과 SushiSwap의 차이점은?</h3>
<pre><code>유니스왑과 스시스왑의 차이점은 보상</code></pre><p><a href="%5B%EB%A7%81%ED%81%AC%5D(https://academy.shrimpy.io/post/uniswap-vs-sushiswap-which-defi-exchange-is-better)">유니스왑과 스시스왑의 차이 자세히 보기</a></p>
<h3 id="🐚-인터넷-카지노의-시대를-열게된-도박-dapp은-어떤-문제를-해결했나요">🐚 인터넷 카지노의 시대를 열게된 도박 dApp은 어떤 문제를 해결했나요?</h3>
<pre><code>중간 개입자가 없고 투명하기 때문에 사기가 덜해졌지만,
카지노 도박장 또는 토토 사이트가 사라지는 러그풀(rug-pull)은 아직도 존재하는듯하다.</code></pre><h3 id="🐚-대출과-보험관련-dapp들은-어떻게-믿을수-있나요">🐚 대출과 보험관련 dApp들은 어떻게 믿을수 있나요?</h3>
<pre><code>스마트컨트랙트이고 누구나 볼 수 있다는 투명성을 갖고있기 때문에?</code></pre><h3 id="🐚-dex와-uniswap의-차이점은">🐚 DEX와 Uniswap의 차이점은?</h3>
<pre><code>? 유니스왑은 DEX입니다.
CEX와 DEX의 차이점이라함은 중앙화되어있지않다는 점, 자동화된 시장 메이커(Auto Market Maker, AMM)가
존재한다는 것이다.</code></pre><h3 id="🐚-전통적인-어플리케이션에서-토큰을-사용하는-이유는">🐚 전통적인 어플리케이션에서 토큰을 사용하는 이유는?</h3>
<pre><code>? 전통적은 어플리케이션에션은 대게 토큰을 사용하지 않습니다. (굳이 사용하고있는거라면 마일리지?)
DApp에서 토큰을 사용하는 이유에는 비트코인에서의 채굴자들에게 참여성을 부여하여 지속가능성을 주기위해서,
또는 스마트컨트랙트를 사용하기때문에 토큰을 사용하는것이지 않을까요?</code></pre><h3 id="🐚-실제-국내에서-사용되는-블록체인-기반-dapp에-대해-알고있나요">🐚 실제 국내에서 사용되는 블록체인 기반 dApp에 대해 알고있나요?</h3>
<pre><code>아이콘루프의 DID기반 DApp
클레이튼 생태계에 올라오는 모든 DApp</code></pre><h3 id="🐚-dapp이-해결해나아가야하는-문제점은-어떤게-있을까요-그리고-그-해결책은-어떻게-되나요">🐚 dApp이 해결해나아가야하는 문제점은 어떤게 있을까요? 그리고 그 해결책은 어떻게 되나요?</h3>
<pre><code>속도·수수료문제 / 어려운 사용성 문제 / 가격변동성 / 규제
→ 속도와 수수료문제는 solana, bsc, terra, polygon 같은 다양한 플랫폼들이 탄생함에따라 
개선되어가고있으며 이더리움또한 문제 해결을 위해 이더리움2.0과 같은 여러 연구를 하고있다.

사용성 문제는 아직 블록체인 기술이 보편적이지 않아서 어려움을 느끼고있다고 생각한다. 막상 해보면
어렵지않은데 두려움을 느끼지 않도록 UI/UX를 사용자친화적이게 만들어야하며, 누구나 블록체인을
알수있도록 하는 것 또한 우리의 임무라고 생각한다.

아무래도 비트코인을 포함한 모든 코인들이 가격변동성이 심각하긴하다.
그로인해 달러기반으로 발행되는 스테이블코인이 등장하였으며 마켓볼륨이 점차적으로 증가하고있고
사용도도 늘어난다면 앞으로 스테이블기반 DApp의 사용도도 많아질 것 같다. 

규제부분은 난 모르겠다... 정부입장에서도 사실 탈중앙화를 한다는데 좋아할 리가 없겠지만
무작정 규제를 때리는것보다 서로 합의점을 찾아서 잘 해결되었으면 좋겠다

위 모든 문제들은 블록체인이 발전함에 따라 개선해나아갈 것이고 자연스럽게 우리 삶의 스며들지 
않을까 생각한다.</code></pre>]]></description>
        </item>
    </channel>
</rss>