[BlockChain] 사과 판매 앱 만들기

2022. 12. 6. 10:41·개발/BlockChain
728x90
반응형

1. 초기 설정

트러플 초기 설정

npx truffle init

가나쉬 실행

npx ganache-cli

리액트 폴더 만들기

npx create-react-app myapp

src 폴더 안에 contracts폴더 생성

 

truffle-config.js

module.exports = {
  contracts_build_directory: "myapp/src/contracts",
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*",
    },
  },

  compilers: {
    solc: {
      version: "0.8.17",
    },
  },
};

contracts_build_directory : 배포시 빌드되는 폴더를 정해준다.

 

migrations/2_deploy_AppleShop.js

const AppleShop = artifacts.require("AppleShop");

module.exports = function (deployer) {
  deployer.deploy(AppleShop);
};

2. 스마트 컨트랙트

contracts/AppleShop.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract AppleShop{
    mapping(address => uint) myApple;

    // 사과 구매 함수
    function buyApple() public payable {
        myApple[msg.sender] += 1;
    }
    
    // 사과 전체 판매 함수
    function sellApple(uint applePrice) public payable{
        uint256 refund = myApple[msg.sender] * applePrice;
        myApple[msg.sender] = 0;
        payable(msg.sender).transfer(refund);
    }
    
    // 가지고 있는 사과 확인 함수
    function getApple() view public returns(uint){
        return myApple[msg.sender];
    }
}

배포

npx truffle migration

3. 프론트

(1) 커스텀 훅

myapp/src/hooks/useWeb3.js

import React, { useEffect, useState } from "react";
import Web3 from "web3/dist/web3.min.js";

const useWeb3 = () => {
  const [account, setAccount] = useState();
  const [web3, setWeb3] = useState();
  const getRequestAccount = async () => {
    const [account] = await window.ethereum.request({
      method: "eth_requestAccounts",
    });
    return account;
  };
  useEffect(() => {
    (async () => {
      const account = await getRequestAccount();
      const web3 = new Web3(window.ethereum);
      setAccount(account);
      setWeb3(web3);
    })();
  }, []);
  return [web3, account];
};

export default useWeb3;

(2) 컴포넌트

myapp/src/components/AppleShop.js

import React, { useEffect, useState } from "react";
import AppleShopContract from "../contracts/AppleShop.json";
const AppleShop = ({ web3, account }) => {
  const [apple, setApple] = useState();
  const [deployed, setDeployed] = useState();
  const [CA, setCA] = useState();
  // 사과 구매하기 버튼 함수
  const buy = async () => {
    await deployed.methods.buyApple().send({
      from: account,
      to: CA,
      value: web3.utils.toWei("1", "ether"),
    });
    const currentApple = await deployed.methods.getApple().call();
    setApple(currentApple);
  };
  // 사과 판매하기 버튼 함수
  const sell = async () => {
    const eth = web3.utils.toWei("1", "ether");
    await deployed.methods.sellApple(eth).send({
      from: account,
      to: CA,
    });
    const currentApple = await deployed.methods.getApple().call();
    setApple(currentApple);
  };
  useEffect(() => {
    (async () => {
      if (!web3) return;
      const networkId = await web3.eth.net.getId();
      const instance = await new web3.eth.Contract(
        AppleShopContract.abi,
        AppleShopContract.networks[networkId].address
      );
      // 인스턴스 객체 사과 갯수 가져오는 함수
      const currentApple = await instance.methods.getApple().call();
      setApple(currentApple);
      setDeployed(instance);
      setCA(AppleShopContract.networks[networkId].address);
    })();
  }, []);
  return (
    <div>
      <div>사과 한개 가격 : 1ETH</div>
      <div>내가 가지고 있는 사과 : {apple} 개</div>
      <button onClick={buy}>구매하기</button>

      <div>사과 판매 가격 : {apple} ETH</div>
      <button onClick={sell}>사과 전체 판매하기</button>
    </div>
  );
};

export default AppleShop;

(3) App.js

myapp/src/App.js

import React from "react";
import "./App.css";
import AppleShop from "./components/AppleShop";
import useWeb3 from "./hooks/useWeb3";
function App() {
  const [web3, account] = useWeb3();
  if (!account) return <h1>메타마스크를 연결해주세요</h1>;
  return (
    <div className="App">
      <h2>사과 앱</h2>
      <AppleShop web3={web3} account={account} />
    </div>
  );
}

export default App;
728x90
반응형

'개발 > BlockChain' 카테고리의 다른 글

[BlockChain] ERC20 Token - openzeppelin 사용  (1) 2022.12.06
[BlockChain] ERC20 Token 만들기  (0) 2022.12.06
[BlockChain] 스마트컨트랙트로 투표 Dapp 만들기  (0) 2022.12.06
[BlockChain] 메타마스크 토큰추가  (1) 2022.12.06
[BlockChain] ganache, react, express로 메타마스크 연결하기  (0) 2022.12.05
'개발/BlockChain' 카테고리의 다른 글
  • [BlockChain] ERC20 Token - openzeppelin 사용
  • [BlockChain] ERC20 Token 만들기
  • [BlockChain] 스마트컨트랙트로 투표 Dapp 만들기
  • [BlockChain] 메타마스크 토큰추가
TeTedo.
TeTedo.
  • TeTedo.
    TeTedo 개발 일기
    TeTedo.
  • 전체
    오늘
    어제
    • 분류 전체보기 (319)
      • 개발 (274)
        • Article (4)
        • 정리 (21)
        • Spring Boot (17)
        • JPA (2)
        • JAVA (6)
        • Database (4)
        • 자료구조 (11)
        • 알고리즘 (32)
        • React (20)
        • Docker (10)
        • node.js (18)
        • Devops (11)
        • Linux (4)
        • TypeScript (3)
        • Go (10)
        • HyperLedger (4)
        • BlockChain (43)
        • html, css, js (48)
        • CS (3)
        • AWS (3)
      • 모아두고 나중에 쓰기 (3)
      • 팀프로젝트 (18)
        • SNS(키보드워리어) (9)
        • close_sea (9)
      • 개인프로젝트 (1)
        • Around Flavor (1)
        • CHAM (13)
        • ethFruitShop (5)
      • 독서 (0)
        • 스프링부트와 AWS로 혼자 구현하는 웹 서비스 (0)
  • 블로그 메뉴

    • 홈
    • 개발일기
    • CS
    • 실습
    • 코딩테스트
    • 웹
    • Go
    • node.js
    • 팀플
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    mysql
    node
    nodejs
    명령어
    erc20
    React
    30일챌린지
    컨테이너
    30일 챌린지
    하이퍼레저
    도커
    node.js
    go언어
    프로그래머스
    go
    ERC721
    html
    js
    블록체인
    CSS
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
TeTedo.
[BlockChain] 사과 판매 앱 만들기
상단으로

티스토리툴바