안녕하세요.
오늘은 지난 4월 1일에 진행된 모나드 부트캠프 2일차에 대한 내용을 정리해 보겠습니다.
아래 제공한 코드는 기초님께서 작성해주신 코드를 인용하였습니다.
기초코인수급자
You can view and join @gichocoin right away.
t.me
2일 차 : Solidity 심화
내용 :
- Monad dapp team Yield Kingz 강연
- Solidity 문법
- 스마트 컨트렉트 구현
Yield Kingz 대표님 강연
항상 VC들 만날 때 마다 받는 질문 = mass adoption 어떻게 할 거냐
메스 어뎁션 : 블록체인 기술이나 암호화폐가 대중적으로 수용되고 널리 사용되는 상태
쉽게 말해, 어떻게 유저들을 모을 거냐?
-> 현재 WEB2 버전을 만들어 배포완료, play store나 app store에 등록되어 있음. WEB2 유저들은 확보한 상태. 이들을 WEB3로 이끌어 올 것이다.
그럼 또 WEB2 유저들은 어떻게 이끌어 올 거임?
에어드랍 방식? 잘 모르게씀
Yeild Kingz는 무슨 프로젝트?
WEB3에서의 온라인 카지노
카지노를 선택한 이유?
1. 카지노 출입자는 돈을 잃을 때까지 플레이한다. -> 카지노가 돈을 버는 방법
2. 만국 공통 룰을 가지고 있고 100년째 변하지 않았다. -> 접근성 높다?
3. 그럼 왜 게임이냐? -> 사용처가 많다.
개발자 입장에서 블록체인은 비효율적이다.
-> 기술적으로 좋은 건 맞으나 비효율적이다. fully onchain이 거의 불가능하다.
Fully Onchain : 블록체인 기술에서 모든 활동, 데이터, 트랜잭션, 그리고 계약이 완전히 블록체인 내부에서 실행되고 저장되는 것을 의미. 이는 외부 시스템이나 오프체인 프로세스에 의존하지 않고 블록체인 자체의 인프라를 활용하는 방식
복습
스마트 컨트랙트 = 돈의 프로그래밍화
컨트랙트 = 계약 -> 특정 조건 하에 약속을 하는 공식적인 합의
돈은 자동화, 프로그래밍화 할 수 없다.
그러나 스마트 컨트랙트로는 가능하다. -> 블록체인 상에서 smart 한 계약으로 프로그래밍된 조건이 충족되면 자동으로 계약이 이행된다.
비유하자면 스마트 컨트랙트 = 디지털 자판기
그리고 제 3자 없이 디지털에서 가치의 전송과 결제를 위해 만들어진 것이 비트코인
비트코인의 스마트 컨트랙트 :
가능하다. - 스크립트 언어로 작동
그러나 단순한 조건부 논리, 멀티시그- 타임락 가능
멀티시그 (Multi-Signature) 정의: N개의 공개키 중 M개의 서명이 필요하도록 설정 (예: 2-of-3).
사용 사례: 자산의 분산 관리, 공동 계정, 탈중앙화된 의사결정.
타임락 (Timelock) CheckLockTimeVerify (CLTV) :
절대 시간 기반 잠금 (특정 블록 높이/유닉스 타임스탬프).
예: 1735689600 (2025년 1월 1일) 이후에만 자금 사용 가능.
CheckSequenceVerify (CSV) :
상대 시간 기반 잠금 (트랜잭션 확인 후 경과 시간).
예: 1,000 블록 이후에 잠금 해제.
그러나 비트 맥시들은 확장성보다 보안에 중점을 둔다.
이더리움 : 스마트 컨트랙트를 작동하기 위한 플랫폼
스마트 컨트랙트의 특징 :
자동실행 = 사람이 해석하거나 결과에 대해 협상할 필요 또는 기다릴 필요가 없다.
예측 가능한 결과 = 언제 어떻게 시행하더라도 같은 결과가 발생한다.
공개된 기록 = 모든 것이 블록체인에 기록되어 있다.
Privacy 보호 = Address는 공개되어 있지만, 이것은 개개인의 정확한 identit가 아니므로 익명으로 남을 수 있다.
누구나 확인할 수 있는 계약 조건 : 스마트 컨트랙트에 사인하기 전에 계약 조건을 누구나 확인할 수 있다.
블록체인에서는 코드가 법이다.
탈중앙화 : 모든 것은 스마트 컨트랙트로 이루어져 있고, 이루어질 수 있다.
gas가 허락하는 한에서
이더리움 주소가 존재하는 컨트랙트는 불변이다. (upgradable)
실습
VS code 사용
hardhat 설치 : 작업할 디렉터리로 이동
터미널에서 아래 명령어 입력
npm install hardhat
npx hardhat init
hardhat.config.js
Hardhat이라는 이더리움 스마트 컨트랙트 개발 도구에서 사용하는 설정 파일
스마트 컨트랙트를 어떻게 컴파일할지, 어떤 네트워크에 배포할지 같은 내용을 담고 있다.
require("@nomicfoundation/hardhat-toolbox"); // 자주 쓰이는 플러그인들을 모아둔 패키지
const DEFAULT_COMPILER_SETTINGS = {
version: "0.8.28", // 솔리디티 버전
settings: {
optimizer: { // 최적화 설정
enabled: true,
runs: 200,
},
},
metadata: {
bytecodeHash: "none", // 바이트코드에 해시 값을 포함하지 않는다.
},
};
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
compilers: [DEFAULT_COMPILER_SETTINGS],
},
networks: { // 사용할 블록체인 네트워크 지정
hardhat: {
chainId: 31337, // 고유한 체인 ID
},
monad: {
url: "https://testnet-rpc.monad.xyz",
accounts: [""], // 배포에 사용할 지갑 . 개인주소 프라이빗 키 입력
},
},
};
Split50.sol 파일 생성
직접 만든 스마트 컨트랙트를 저장하고 관리하기 위해 생성
이번 스마트 컨트렉트는 5:5로 이더를 분배하도록 작성
// SPDX-License-Identifier: MIT
// 라이선스 표기 (오픈소스 사용 허용)
pragma solidity ^0.8.0;
// 이 스마트 컨트랙트는 Solidity 0.8.0 이상에서 작동함
contract Split50 {
// 이더를 받을 두 명의 주소를 배열로 저장 (블록체인에 영구 저장됨)
address[2] public recipients;
// 생성자: 컨트랙트가 배포될 때, 받을 사람의 주소 2개를 설정
constructor(address _addr1, address _addr2) {
recipients[0] = _addr1;
recipients[1] = _addr2;
}
// 이더를 보낼 때 호출되는 함수
// 이더를 보내면, 자동으로 반반 분배해줌
function split() external payable {
require(msg.value > 0, "Must send some ether");
// 조건: 0보다 큰 이더를 보내야 실행됨
uint256 half = msg.value / 2;
// 절반 계산
// 첫 번째 수신자에게 절반 전송
(bool sent1, ) = recipients[0].call{value: half}("");
require(sent1, "Transfer to recipient 1 failed");
// 전송 실패하면 에러 발생
// 두 번째 수신자에게 나머지 전송 (잔돈이 생길 경우 보정)
(bool sent2, ) = recipients[1].call{value: msg.value - half}("");
require(sent2, "Transfer to recipient 2 failed");
}
// 수신자 주소 2개를 새로 설정하는 함수 (예시로 작성됨)
function updateRecipients(address[2] memory _newRecipients) public {
recipients
deploy.js 파일 생성
Split50 스마트 컨트랙트를 Monad 테스트넷에 배포하는 스크립트
블록체인에 컨트랙트를 배포
// ethers.js 라이브러리에서 ethers 객체를 가져옴 (스마트 컨트랙트 배포 및 호출에 사용)
const { ethers } = require("ethers");
// hardhat runtime environment 객체를 가져옴 (하드햇 관련 기능 실행 가능)
const hre = require("hardhat");
async function main() {
// 1. 컨트랙트를 컴파일함 (artifacts 폴더 생성됨)
await hre.run("compile");
// 2. 컴파일된 Split50 컨트랙트의 ABI와 바이트코드 가져오기
const artifact = await hre.artifacts.readArtifact("contracts/test2.sol:Split50");
const abi = artifact.abi; // ABI (Application Binary Interface)
const bytecode = artifact.bytecode; // EVM 바이트코드
// 3. Monad 테스트넷의 JSON-RPC 엔드포인트를 이용해 provider 객체 생성
const provider = new ethers.JsonRpcProvider("https://testnet-rpc.monad.xyz");
// 4. 배포자 지갑과 수신자 지갑 생성 (프라이빗 키 직접 입력 필요)
const wallet = new ethers.Wallet("<YOUR_PRIVATE_KEY1>", provider); // 배포자
const wallet2 = new ethers.Wallet("<YOUR_PRIVATE_KEY2>", provider); // 이더 분배 수신자
// 5. 배포자 지갑의 이더 잔액 조회
const balance = await provider.getBalance(wallet.address);
// 6. 배포자 주소 설정
const deployer = wallet.address;
// 7. 배포자 주소와 잔액 출력
console.log("Deploying contracts with the account:", deployer);
console.log("Account balance:", ethers.formatEther(balance), "ETH");
// 8. 컨트랙트 팩토리 객체 생성 (배포할 준비)
const contractFactory = new ethers.ContractFactory(abi, bytecode, wallet);
// 9. 배포 시작
console.log("Deploying contract...");
const contract = await contractFactory.deploy(deployer, wallet2.address);
// Split50 컨트랙트는 생성자에서 주소 2개를 받음
// 10. 트랜잭션 해시 출력 (배포 추적용)
console.log("Deployment Tx Hash:", contract.deploymentTransaction().hash);
// 11. 실제 배포된 스마트 컨트랙트 주소 출력
console.log("Contract deployed to:", contract.target);
}
// 위 main() 함수 실행
main()
.then(() => process.exit(0)) // 정상 종료
.catch((error) => {
console.error(error); // 에러 출력
process.exit(1); // 비정상 종료
});
터미널에 아래 코드 입력
npx hardhat run 위파일이름 --network monad
저 같은 경우는 "npx hardhat run deploy3.js -network monad" 입니다.
위처럼 deploy 된 컨트랙트 주소 확인 가능
0xb40AB5C5891855D9C93B02cAd629A61573303372
위 주소를 monad.explorer에 가서 입력하면 확인 가능
https://testnet.monadexplorer.com/
MonadExplorer | Monad Explorer
MonadExplorer is Layer 1 Monad blockchain explorer, where you can explore transactions, blocks, accounts, tokens and dive into immersive Monad data visualization through Block Explorer, Token Data Analysis, Statistics tools.
testnet.monadexplorer.com
split.js 파일 생성
이 파일은 위에서 배포된 Split50 컨트랙트에 연결해서 split() 함수(5대 5로 나누는 계약) 실행
const { ethers } = require("ethers");
async function main() {
// 모나드 테스트넷에 연결할 Provider 생성
const provider = new ethers.JsonRpcProvider("https://testnet-rpc.monad.xyz");
// 지갑 생성 (프라이빗 키와 연결)
const wallet = new ethers.Wallet(
"", // 여기에 프라이빗 키 입력 (절대 깃허브 등에 공개 금지)
provider
);
// 이미 배포된 Split50 컨트랙트 정보 불러오기
const artifact = await hre.artifacts.readArtifact("contracts/test2.sol:Split50");
const abi = artifact.abi;
// 배포된 컨트랙트 주소와 연결
const contract = new ethers.Contract(
"", // 여기에는 "Contract deployed to:" 라고 출력된 주소 입력
abi,
wallet
);
// split() 함수 실행 - 0.001 ETH(모나드)를 보내고, 50:50으로 나눔
const tx = await contract.split({ value: ethers.parseEther("0.001") }); // 전송할 모나드 양 입력
console.log(tx.hash); // 트랜잭션 해시 출력
console.log("Split 0.001 ether");
}
// 실행 및 에러 처리
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
터미널에 아래 코드 입력
npx hardhat run 작업폴더/split.js --network monad
저 같은 경우는 "npx hardhat run split2.js --network monad" 입니다.
입력하면 스마트 컨트랙트가 실행된 트랜잭션 해시값이 나오게 됩니다.
0xa11c39479f0214fefb8a89a27125f1e24fb0c9b0f3d65356946c4de97cc21d4a
해시값을 다시 한번 explorer에 입력하면 상세내용을 확인할 수 있습니다.
'블록체인 실습' 카테고리의 다른 글
모나드 빌더 부트캠프 - Phase 1 - 3일차 정리 2 (1) | 2025.04.13 |
---|---|
모나드 빌더 부트캠프 - Phase 1 - 3일차 정리 (0) | 2025.04.13 |
모나드 빌더 부트캠프 - Phase 1 - 1일차 정리 (0) | 2025.04.04 |
빗썸 예측차트 서비스 분석 및 실제 사용 후기 (1) | 2025.01.31 |
2024 핀테크 전문가 과정: 핀테크 PO(Product Owner) One Day FinTech 실습 프로젝트 후기 (4) | 2024.11.22 |