8&9. Solidity(Chainlink Mix&토큰)

정예찬·2022년 8월 3일
0

solidity

목록 보기
10/13

본 글은 freeCodeCamp.Org의 Youtube 영상 'Solidity, Blockchain, and Smart Contract Course – Beginner to Expert Python Tutorial'와 관련 코드인 SmartContract의 Github 코드를 기초로 작성되었다.

Youtube 영상 링크: https://www.youtube.com/watch?v=M576WGiDBdQ&t=10336s
Github 코드 링크: https://github.com/smartcontractkit/full-blockchain-solidity-course-py
오늘의 코드: https://github.com/smartcontractkit/chainlink-mix
: https://github.com/PatrickAlphaC/erc20-brownie-py

이번 포스팅은 유튜브 영상 08:21:02~08:34:53에 해당하는 내용이다.

영상의 Lesson 8과 Lesson 9을 하나로 묶어서 포스팅하겠다. 둘이 묶어도 분량이 13분 41초밖에 되지 않는다.

Smart Contract를 작성하든, 다른 코드를 작성하든 코드가 복잡해질수록 모든 코드를 일일이 작성하기가 힘들다. 따라서 코딩 작업 수준이 고급화될수록 이미 특정 목적을 위해 작성된 코드 템플릿을 가져와 쓰는 경우가 많아진다.
brownie에도 여러 code template이 있다. brownie의 템플릿을 brownie mix라고 하는데, 아래 링크에서 brownie mix를 확인할 수 있다.
https://github.com/brownie-mix
우리가 활용할 mix는 chainlink-mix이다. 앞선 포스팅에서도 몇 번 활용했는데, 이 mix를 VS Code에도 추가할 수 있다.

brownie bake chainlink-mix

위 코드를 터미널에 입력하면 chainlink 폴더 안에 chainlink-mix에 해당하는 repository(자료 모음)이 다운로드된다. 필요한 자료를 골라서 활용하면 된다.

다음으로 ERC20 토큰에 대해 알아보자.
ERC20 토큰이란 ERC20 token standard에 활용되는 토큰이다. ERC20은 이더리움 네트워크에서 정한 표준 토큰 형식 중 하나이다. ERC20은 ERC677, ERC777 등 다른 Ethereum Token과도 호환이 된다.
영상에서 여러 Ethereum Token 중 ERC20을 다루는 이유는 ERC20이 가장 대표적인 토큰이기 때문이다. Tether, Chainlink, Unitoken, Dai 모두 ERC20이다.
ERC20을 만드는 목적으로는 거버넌스 토큰으로 이용, 기본 네트워크(underlying network) 보안화, 합성자산(Synthetic Asset) 생성 등이 있다.(각각의 내용이 궁금하다면 검색해보라!)

brownie를 이용해 ERC20을 만들어보자.

mkdir ERC20-BROWNIE
cd ERC20-BROWNIE
brownie init

demos 폴더 안에 ERC20-BROWNIE 폴더를 만들고 brownie로 initialize 해주자.
contracts 폴더에 OurToken.sol을 만들자.

ERC20을 만들기 위해 아래 링크에서 코드를 일일이 긁을 수도 있다.
https://eips.ethereum.org/EIPS/eip-20
하지만 이미 ERC20을 만들 수 있는 코드가 OpenZepplin에 제공되어 있기에 해당 코드를 긁어오자. 아래 링크에 들어가면 코드가 바로 나온다.
https://docs.openzeppelin.com/contracts/4.x/erc20

// contracts/OurToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract GLDToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("OurToken", "OT") {
        _mint(msg.sender, initialSupply);
    }
}

OurToken.sol에 긁어온 코드를 붙여넣은 후 3가지만 수정을 하자.
GLDToken을 OurToken으로,
Gold, GLD를 각각 OurToken, OT로 변경해주자.
이로써 우리의 토큰 이름은 OurToken, 토큰 심볼은 OT가 되었다.

brownie-config.yaml 파일을 만들고 아래 코드를 추가해주자.

dependencies:
 - OpenZeppelin/openzeppelin-contracts@4.2.0
compiler:
 solc:
  remappings:
    - '@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.2.0'
dotenv: .env
wallets:
  from_key: ${PRIVATE_KEY}

OurToken.sol에서 @openzepplin을 import하기 위한 dependencies와 remappings를 추가해주었다. openzeppelin의 버전은 4.2.0으로 설정하였다. 아래 링크는 openzepplin-contracts의 github repository 주소이다.
https://github.com/OpenZeppelin/openzeppelin-contracts
나머지 코드는 익숙하기에 설명은 생략하겠다.

여느 때처럼 .env파일과 그 내용도 아래와 같이 추가해주자.

export PRIVATE_KEY = 0xb5e857091a491a306f8a13ac49ed53655f51c2d780db0e9faf0305878b3f8fe5
export WEB3_INFURA_PROJECT_ID=a9c5bc0ec75c4a83a3e48086df81acfe
export ETHERSCAN_TOKEN=BEF1HMKFS34JWYP6RQACG8S3MX6G4FN4N4

아래 코드를 터미널에 입력해 OurToken.sol을 컴파일해주자.

brownie compile

다음으로 OurToken을 deploy하기 위한 작업을 해주자.
scripts에 들어가 '__init__.py'를 추가해주자.
'helpful_scripts.py'를 추가한 후 아래 코드를 입력해주자.

from brownie import accounts, network, config

LOCAL_BLOCKCHAIN_ENVIRONMENTS = [
    "development",
    "ganache",
    "hardhat",
    "local-ganache",
    "mainnet-fork",
]


def get_account(index=None, id=None):
    if index:
        return accounts[index]
    if network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        print(accounts[0].balance())
        return accounts[0]
    if id:
        return accounts.load(id)
    return accounts.add(config["wallets"]["from_key"])

Local 체인을 정하고 get_account 함수를 정의하고 있다.
LOCAL_BLOCKCHAIN_ENVIRONMENTS에 해당하는 개발 환경을 보면 이전에 우리가 작성한 내용과 조금 달라졌음을 알 수 있다. 영상에서는 helpful_scripts에 대한 별도의 설명을 하지 않고 복사-붙여넣기하라고 이야기한다. 필자 추측에는 LOCAL_BLOCKCHAIN_ENVIRONMENTS의 이러한 정의가 표준적인 정의인 듯하다. 'hardhat'도 'ganache'와 비슷한 개발 환경이다.
get_account 함수 또한 별도로 설명할 내용은 없어보인다. LOCAL_BLOCKCHAIN_ENVIRONMENTS가 활성화된 경우 계좌의 잔고를 print한다는 점만 조금 특별해보인다.

마지막으로 OurToken을 deploy하기 위해 1_deploy_token.py파일을 scripts에 만들고 다음 코드를 채워주자.

from brownie import OurToken
from scripts.helpful_scripts import get_account
from web3 import Web3

initial_supply = Web3.toWei(1000, "ether")


def main():
    account = get_account()
    our_token = OurToken.deploy(initial_supply, {"from": account})
    print(our_token.name())

OurToken.sol의 constructor는 initial_supply, 즉 토큰의 초기 공급 개수를 Wei 단위로 입력받는다. 따라서 initial_supply에 1000*10^18을 저장해주었다.
다음으로 계좌를 가져와 그 계좌로 OurToken을 deploy한 후 생성된 Token의 이름을 출력하고 있다.

지금까지 작성한 코드를 모두 저장한 후 OurToken을 rinkeby network에서 deploy해보자.

brownie run scripts/1_deploy_token.py --network rinkeby

OurToken이 deploy된 주소를 복사하여 rinkeby etherscan에서 검색해보자.

OurToken이 생성되었음을 확인할 수 있다.
다음으로 Metamask->토큰 가져오기->토큰 계약 주소에 OurToken이 deploy된 주소(이 경우: 0x0b63D94849CE4733226477863BA79F3413505075) 입력->맞춤형 토큰 추가
위 과정을 완료하면 Metamask에 1000OT가 추가되었음을 확인할 수 있다.

만들어진 토큰을 쉽게 거래할 수도 있다. 아래 링크에 들어가 Metamask 지갑을 연결하자.
https://app.uniswap.org/
풀->추가->풀 만들기를 누르면 유동성 추가 인터페이스가 등장한다. 원하는 대로 내용을 입력해주고 승인을 해주면 거래 풀이 생성된다. 그러나 실제로 승인을 하지는 말자. 해도 아무도 풀에 참여하지 않는다.

이제 4개(Epilogue까지 5개)의 포스팅을 남겨두고 있다. 벌써 이만큼이나 왔다. 그러나 남은 4개의 포스팅은 커버할 내용이 많다. 특히 마지막 포스팅은 영상 길이가 3시간을 훌쩍 넘는다. 마지막 포스팅을 작성하는 주에 사회로 나간다. 포스팅의 성취감과 군생활을 무사히 마무리했다는 성취감을 모두 만끽하며 사회로 나가고 싶다. 포스팅 읽어줘서 너무 고맙고 다음 포스팅에서 만나자!!!

MIT License

Copyright (c) 2021 SmartContract

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
profile
BlockChain Researcher

0개의 댓글