단계별: OnFlow 에뮬레이터를 사용하는 ReactJS dApp

이 자료는 (Yavhen Vitiv) 덕분에 만들어졌습니다!
__
백엔드 부분이 중앙 집중식 서버에서 실행되는 기존 애플리케이션과 달리 dApp의 백엔드 코드는 OnFlow 네트워크와 같은 분산형 네트워크에서 자율적으로 실행됩니다.



스마트 계약은 미리 정해진 조건이 충족될 때 실행되는 계약 실행에 사용되는 프로그램입니다. 이를 통해 관련 당사자는 자금을 안전하게 해제하고, 차량을 등록하고, 티켓을 발행하고, 중개자 없이 알림을 보낼 수도 있습니다.

스마트 계약은 높은 수준의 보안과 투명성, 속도, 정확성 및 눈에 띄는 비용 효율성을 제공합니다. 의료, 유통, 소매 등 다양한 산업에서 사용할 수 있습니다.
dApp은 블록체인에 배포된 스마트 계약과 상호 작용할 수 있습니다.



블록체인 네트워크에서 스마트 계약과 상호 작용하는 클라이언트 측 애플리케이션을 구축하는 방법

우리가 만들려는 애플리케이션은 다음과 같은 기능을 갖습니다.
  • 로그인 및 로그아웃 버튼
  • 사용자 프로필
  • 사용자 프로필 업데이트 기회
  • 블록체인 네트워크에 직접 연결된 계정 주소

  • 1단계. 종속성 설치


  • NPM(노드 패키지 관리자) 설치
  • 로컬 에뮬레이터를 실행하기 위해 Flow CLI를 설치합니다
  • .
  • fcl-dev-wallet 저장소를 별도의 폴더에 복제하여
    dev 지갑 실행 및 npm 설치

  • 2단계. ReactJS dApp 및 npm 패키지 설정



    ReactJS dApp 생성:npx create-react-app my-first-dapp
    my-first-dapp 디렉터리에서 OnFlow 패키지를 설치합니다.
    npm i @onflow/fcl @onflow/types

    3단계. Tailwind CSS 설정



    이 단계는 선택 사항이지만 원하는 경우 수행할 수 있습니다read how to set up Tailwind CSS.

    4단계. 개발자 지갑으로 로컬 에뮬레이터 실행



    fcl-dev-wallet 리포지토리에서 다음 두 명령을 실행해야 합니다.flow emulator
    npm run dev

    5단계. 로그인 및 로그아웃 버튼이 내장된 AppJS 구성 요소 만들기



    src/AppJS 파일에서 로그인 및 로그아웃 논리로 AppJS 구성 요소를 만들 수 있습니다.

    mport * as fcl from "@onflow/fcl";
    
    import './App.css';
    import { useEffect, useState } from "react";
    
    fcl
        .config()
        // Point App at Emulator REST API
        .put("accessNode.api", "http://localhost:8888")
        // Point FCL at dev-wallet (default port)
        .put("discovery.wallet", "http://localhost:8701/fcl/authn")
    
    
    function App() {
    
        const [isLogged, setIsLogged] = useState(false);
        const [user, setUser] = useState();
    
        useEffect(() => {
            fcl.currentUser.subscribe((account) => {
                setUser(account);
                setIsLogged(account.addr)
            });
        }, [])
    
        const logIn = () => {
            fcl.authenticate();
        }
    
        const logOut = () => {
            fcl.unauthenticate();
        }
    
        return (
            <div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
                {isLogged ? (
                    <div className="p-3">
                        <h3 className="text-2xl">{user.addr}</h3>
                        <button onClick={logOut}
                                className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                            Logout
                        </button>
                    </div>
                ) : (
                    <button onClick={logIn}
                            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                        Login
                    </button>
                )}
            </div>
        );
    }
    
    export default App;
    


    6단계. ReactJS dApp 실행



    npm-start 명령을 실행하고 페이지를 엽니다http://localhost:3000/.

    Step 7. 최초의 스마트 컨트랙트 생성



    fcl-dev-wallet/cadence/contract 디렉터리에 Profile.cdc 파일을 만듭니다.



    fcl-dev-wallet/flow.json 디렉터리의 구성 파일에 스마트 계약을 추가합니다.

    {
      
      "contracts": {
        "Profile": {
          "source": "./cadence/contracts/Profile.cdc"
          "aliases": {
            "emulator": "0xee82856bf20e2aa6"
         }
        },
        
      },
      
      "deployments": {
        "emulator": {
          "emulator-account": ["FUSD", "Profile"]
        }
      }
    }
    


    Profile.cdc 파일을 로컬 에뮬레이터에 배포합니다.
    flow project deploy --update

    8단계. 첫 번째 케이던스 스크립트 생성



    블록체인 네트워크에서 데이터 추출:

    const getProfile = async () => {
            const [firstName, lastName, email] = await fcl.send([
                fcl.script`
                import Profile from 0xf8d6e0586b0a20c7
    
                pub fun main(): [String] {
                  return [Profile.firstName, Profile.lastName, Profile.email]
                }
                `
            ]).then(fcl.decode)
    
            setProfile({ firstName, lastName, email })
        }
    view raw
    


    9단계. 첫 번째 블록체인 트랜잭션 생성



    블록체인 네트워크에서 데이터를 수정하기 위해 블록체인 트랜잭션을 생성합니다.

    const updateProfile = async () => {
            const txId = await fcl.send(
                [
                    fcl.transaction`
                    import Profile from 0xProfile
    
                    transaction(newFirstName: String, newLastName: String, newEmail: String) {
    
                      prepare(signer: AuthAccount) {
    
                      }
    
                      execute {
                        Profile.updateProfile(newFirstName: newFirstName, newLastName: newLastName, newEmail: newEmail)
                      }
                    }
                    `,// update profile transaction
                    fcl.args([
                        fcl.arg(profile.firstName, t.String),
                        fcl.arg(profile.lastName, t.String),
                        fcl.arg(profile.email, t.String)
                    ]), // parameters of the transaction
                    fcl.proposer(fcl.authz), // The account that initiate this transaction
                    fcl.payer(fcl.authz), // The account that pays the fee for this transaction (free on local emulator)
                    fcl.authorizations([fcl.authz]), // A list of the accounts that are authorizing this transaction to mutate to their on-chain account state.
                    fcl.limit(9999), // The maximum number of computational units that can be used to execute this transaction.
                ]
            ).then(fcl.decode);
    
            alert(`The transaction executed successfully`);
        }
    


    10단계. 콘텐츠 업데이트



    케이던스 스크립트와 블록체인 트랜잭션을 AppJS 구성 요소에 추가하고 from을 생성하여 콘텐츠(사용자 프로필)를 업데이트합니다.

    import * as fcl from "@onflow/fcl";
    import * as t from "@onflow/types"
    
    import './App.css';
    import { useEffect, useState } from "react";
    
    fcl
        .config()
        // Point App at Emulator REST API
        .put("accessNode.api", "http://localhost:8888")
        // Point FCL at dev-wallet (default port)
        .put("discovery.wallet", "http://localhost:8701/fcl/authn")
        .put("0xProfile", "0xf8d6e0586b0a20c7");
    
    function App() {
    
        const [isLogged, setIsLogged] = useState(false);
        const [user, setUser] = useState();
        const [profile, setProfile] = useState();
    
        useEffect(() => {
            fcl.currentUser.subscribe((account) => {
                setUser(account);
                setIsLogged(account.addr)
                getProfile();
            });
        }, [])
    
        const getProfile = async () => {
            const [firstName, lastName, email] = await fcl.send([
                fcl.script`
                import Profile from 0xProfile
    
                pub fun main(): [String] {
                  return [Profile.firstName, Profile.lastName, Profile.email]
                }
                `
            ]).then(fcl.decode)
    
            setProfile({ firstName, lastName, email })
        }
    
        const updateProfile = async (e) => {
            e.preventDefault();
    
            const txId = await fcl.send(
                [
                    fcl.transaction`
                    import Profile from 0xProfile
    
                    transaction(newFirstName: String, newLastName: String, newEmail: String) {
    
                      prepare(signer: AuthAccount) {
    
                      }
    
                      execute {
                        Profile.updateProfile(newFirstName: newFirstName, newLastName: newLastName, newEmail: newEmail)
                      }
                    }
                    `,// update profile transaction
                    fcl.args([
                        fcl.arg(profile.firstName, t.String),
                        fcl.arg(profile.lastName, t.String),
                        fcl.arg(profile.email, t.String)
                    ]), // parameters of the transaction
                    fcl.proposer(fcl.authz), // The account that initiate this transaction
                    fcl.payer(fcl.authz), // The account that pays the fee for this transaction (free on local emulator)
                    fcl.authorizations([fcl.authz]), // A list of the accounts that are authorizing this transaction to mutate to their on-chain account state.
                    fcl.limit(9999), // The maximum number of computational units that can be used to execute this transaction.
                ]
            ).then(fcl.decode);
    
            console.log(txId);
            alert(`The transaction executed successfully`);
        }
    
        const logIn = () => {
            fcl.authenticate();
        }
    
        const logOut = () => {
            fcl.unauthenticate();
        }
    
        const handleInputChange = (e) => {
            setProfile({ ...profile, [e.target.id]: e.target.value });
        }
    
    
        const profileBlock = profile ? (<div className="border-b-2 block md:flex">
            <div className="w-full p-8 bg-white shadow-md">
                <form onSubmit={updateProfile} autoComplete="off">
                    <div className="pb-6">
                        <label htmlFor="firstName"
                              className="font-semibold text-gray-700 block pb-1">First Name</label>
                        <div className="flex">
                            <input id="firstName" required className="border-1 bg-gray-200 rounded-r px-4 py-2 w-full"
                                  type="text" value={profile.firstName} onChange={handleInputChange}/>
                        </div>
                    </div>
                    <div className="pb-6">
                        <label htmlFor="lastName"
                              className="font-semibold text-gray-700 block pb-1">Last Name</label>
                        <div className="flex">
                            <input id="lastName" required className="border-1 bg-gray-200 rounded-r px-4 py-2 w-full"
                                  type="text" value={profile.lastName} onChange={handleInputChange}/>
                        </div>
                    </div>
                    <div className="pb-6">
                        <label htmlFor="email"
                              className="font-semibold text-gray-700 block pb-1">Email</label>
                        <div className="flex">
                            <input id="email" autocomplete="nope" required
                                  className="border-1 bg-gray-200 rounded-r px-4 py-2 w-full"
                                  type="email" value={profile.email} onChange={handleInputChange}/>
                        </div>
                    </div>
                    <div>
    
                        <button type="submit"
                                className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
                            Update Profile
                        </button>
                    </div>
                </form>
            </div>
        </div>) : '';
    
        return (
            <div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
                {isLogged ? (
                    <div className="p-3">
                        <span className="inline-block text-2xl mr-2">Account address: {user.addr}</span>
                        <button onClick={logOut}
                                className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                            Logout
                        </button>
                        {profileBlock}
                    </div>
                ) : (
                    <button onClick={logIn}
                            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                        Login
                    </button>
                )}
            </div>
        );
    }
    
    export default App;
    


    이제 첫 번째 분산 응용 프로그램을 테스트할 수 있습니다.
    __
    4,000 decentralized applications 정부, 의료 및 도박에도 활용되고 있습니다. 그리고 긍정적인 역동성은 의심할 여지 없이 블록체인 솔루션 채택의 타당성과 수익성을 입증합니다. 그들의 시장 지배력에 대해 말할 때 분산형 앱은 기존 앱을 대체할 가능성이 낮습니다. 그러나 그들은 비즈니스 환경에서 더 많은 모멘텀을 얻을 것으로 예상됩니다.

    고려해야 할 몇 가지 통계는 다음과 같습니다.
  • 하루에 199,000건 이상의 비트코인 ​​거래가 수행됨
  • 전 세계 인구의 10%가 암호화폐를 소유하고 있습니다
  • 미국인의 16%가 암호화폐에 투자했습니다
  • .
  • 글로벌 블록체인 시장은 2026년까지 340억 달러에 이를 것으로 예상됩니다.
    dApps에서 개인 및 비즈니스 데이터는 블록체인 환경에서 별도의 불변 블록에 저장됩니다. 즉, 신생 스타트업과 성숙한 다국적 기업 모두가 직면할 수 있는 가장 심각한 문제 중 하나인 악용으로부터 민감한 데이터를 보호합니다.
  • 좋은 웹페이지 즐겨찾기