세 번째 단계

    그래서, 당신은 기본적인 것입니다. 이전 섹션에서는 스마트 계약을 개발하고 Truffle을 사용하여 배포했습니다. 그러나 이전 섹션에서 스마트 계약은 로컬 개발 네트워크에 배포되었습니다. 사용자 만 작업을 배포하고 해당 로컬 테스트 네트워크와 상호 작용할 수 있기 때문에 재미가 없습니다! 우리는 친구를 원합니다! 다른 사람들이 배포 한 다른 스마트 계약에 대한 액세스!

    따라서이 섹션에서는 공개 이더 리움 테스트 넷을 활용하는 것으로 전환하여 이더 리움 생태계에서 발생하는 모든 작업에 참여할 수 있습니다.!

    시작하자!

    먼저 이러한 공용 이더 리움 네트워크에 액세스하는 방법에 대해 이야기 할 것입니다..

    이러한 네트워크에 액세스하려면 각 네트워크에 연결된 노드에 연결해야합니다. 각 이더 리움 네트워크를 자신의 작은 이더 리움 세계로 볼 수 있으며, 이더 리움 노드를 게이트웨이 또는 각 세계에 대한 액세스 포인트로 볼 수 있습니다! 이더 리움은 분산 네트워크이기 때문에 각 이더 리움 노드는 연결된 네트워크의 전체 상태를 저장하고 (전체 상태를 저장할 필요가 없지만 지금은 걱정하지 않는 노드가 있음) 지속적으로 통신합니다. 네트워크의 다른 노드와 함께 해당 상태를 최신 상태로 유지하십시오! 따라서이 상태에서 읽고 쓸 수 있으려면 이러한 노드 중 하나에 액세스해야합니다..

    현재 사용 가능한 많은 Ethereum 클라이언트 (Hyperledger Besu (ConsenSys에서 개발 한 Java 클라이언트), Geth (Go 클라이언트), Parity (Rust 클라이언트) 등) 중 하나를 사용하여 자신의 노드를 매우 잘 호스팅 할 수 있습니다. 자신의 이더 리움 노드를 호스팅하고 유지하는 데 따른 약간의 DevOps 오버 헤드-특히 안정적으로 수행하려는 경우! 따라서 ConsenSys는 세계적인 이더 리움 인프라 제품인 Infura를 구축했습니다. Infura는 전체 ‘노드 관리’부분을 처리하여 이더 리움 노드 클러스터에 대한 즉각적이고 안정적이며 확장 가능한 액세스를 제공합니다! Infura는“Ethereum-nodes-as-a-Service”라고 생각할 수 있습니다. &# 128578;

    Infura 시작하기

    Infura를 시작하려면 다음에서 계정을 등록해야합니다. infura.io. 걱정하지 마세요. 무료로 시작할 수 있으며 민감한 정보를 입력 할 필요가 없습니다.!

    등록이 완료되면 다음과 같은 페이지로 이동합니다.

    로그인

    이 페이지에서 알 수 있듯이 시작하려면 첫 번째 옵션 “시작하고 이더 리움 네트워크에 액세스 할 첫 번째 프로젝트를 만드십시오!”를 선택합니다.

    원하는대로 프로젝트 이름을 지정할 수 있습니다. “테스트 프로젝트”라는 이름을 지정합니다..

    InfuraNP

    이제 Infura 노드에 액세스하는 데 필요한 자격 증명이 제공됩니다.!

    InfuraC

    이 페이지를 열어 두십시오! 나중에 다시 돌아올 것입니다. &# 128578;

    다음으로 할 일은 새로운 Truffle 프로젝트를 초기화하는 것입니다. Truffle 설치에 도움이 필요하면이 문서의 이전 섹션을 참조하십시오..

    새 Truffle 프로젝트를 초기화하려면 새 폴더를 만들고

    트러플 초기화

    다음으로, 새로 초기화 된 프로젝트에 Truffle HD Wallet 공급자를 추가하여 Infura 노드로 전송되기 전에 트랜잭션에 서명 할 수 있습니다. Ethereum에 대한 모든 상태 변경은 계약 배포, 계약 내 함수 호출 또는 토큰 전송 등 트랜잭션의 형태로 제공됩니다! 각 트랜잭션은 계정에 의해 서명되어야합니다. 따라서 우리의 애플리케이션은 이더 리움에 상태를 변경할 수 있도록 트랜잭션에 서명 할 수있는 기능이 필요합니다.!

    각 거래에는 이더가 필요합니다. 이 거래 비용을 “가스 비용”이라고합니다. 따라서 서명 된 거래가 Infura 노드로 전송 된 후 네트워크에서 처리되도록하려면 이더로 계정에 자금을 조달해야합니다. 이 내용은 나중에 다루 겠지만 이것은 지갑이 필요한 또 다른 중요한 이유입니다. & 지갑 공급자!

    터미널에서 새로 초기화 된 프로젝트 유형에 Truffle HD Wallet 공급자를 추가하려면 :

    npm 설치[email protected] truffle / hdwallet-provider 저장

    이로 인해 몇 가지 경고가 표시 될 수 있지만 설치하는 한 진행하는 것이 좋습니다.!

    이제 애플리케이션에서 사용할 이더 리움 계정을 만들 수 있습니다! 우리의 지갑 제공자는 HD (계층 적 결정 론적) 지갑이므로 동일한 시드 문구 또는 니모닉을 사용하여 결정 론적으로 계정을 생성 할 수 있습니다..

    계정을 만들려면 먼저 Ganache를 시작해야합니다. Ganache는 우리 자신의 로컬 개발 네트워크를 쉽게 만들 수있는 Truffle 제품입니다. 가나슈를 실행하려면 다음을 입력하십시오.

    가나슈 클리

    이 가이드의 2 단계를 완료했다면 Ganache / ganache-cli가 이미 설치되어있을 것입니다. 설치하지 않은 경우 npm 명령을 사용하여 설치할 수 있습니다.

    npm install -g ganache-cli

    또는 원사를 사용하는 경우 

    원사 글로벌 추가 ganache-cli

    다음으로 앱이 Ganache와 통신하도록 허용해야합니다. 프로젝트 디렉토리로 이동하여 truffle-config.js 파일을 확인하고 네트워크에서 다음 줄의 주석 처리를 제거 (또는 추가)하면됩니다.

    개발 : {호스트 : "127.0.0.1", // 로컬 호스트 (기본값 : 없음) 포트 : 8545, // 표준 이더 리움 포트 (기본값 : 없음) network_id : "*" // 모든 네트워크 (기본값 : 없음)},

    비추천

    좋은! 이제 우리 앱은 127.0.0.1:8545에서 실행되는 Ganache 개발 네트워크와 통신 할 수 있습니다! 이제 새 터미널 창 (그러나 여전히 프로젝트 폴더에 있음)에서 다음 명령을 실행합니다.

    트러플 콘솔

     Ganache 네트워크에 연결합니다. 걱정하지 마세요. 나중에 공용 네트워크에 연결할 것입니다! 키를 생성하려면 지금 Ganache에 연결하기 만하면됩니다. &# 128578;

    참고 : 문제가 발생하는 경우 Ganache에서 RPC 서버 포트 번호가 트러플 구성 파일과 일치하는지 확인하십시오. 기본 경우 8545가 작동해야합니다. 그렇지 않으면 구성 파일을 Ganache와 일치하도록 변경하십시오..

    이제 Truffle 콘솔에 다음 명령을 입력하여 지갑을 만듭니다.

    const HDWalletProvider = require ( ‘@ truffle / hdwallet-provider’);

    이로 인해 “정의되지 않음”응답이 발생합니다.

    12 단어 니모닉의 경우 다음과 같은 니모닉 생성기를 사용할 수 있습니다. 이 하나 당신이 원한다면!

    니모닉 (씨앗) 문구를 저장하십시오.! 나중에 필요합니다. &# 128515;

    다음으로 터미널에 다음 명령을 추가합니다 (트러플 개발 중).

    const mnemonic = ‘여기에 12 단어’; const 지갑 = new HDWalletProvider (mnemonic, "http : // localhost : 8545");

    이제 트러플 콘솔에서 다음 명령을 입력하십시오. 

    지갑

    위로 스크롤하면 다음과 같은 계정 목록이 표시됩니다.!

    아빠

    Ganache에 연결되어있는 동안 해당 계정이 생성 되었음에도 불구하고 모든 이더 리움 네트워크에서 동일한 이더 리움 계정을 사용할 수 있습니다. 계정은 네트워크에 따라 다릅니다. 예를 들어 이더 리움 메인 넷에서 거래를하면 해당 거래는 이더 리움 메인 넷에서만 발생하며 다른 네트워크에서는 발생하지 않습니다. 이제 Ganache (로컬 개발 네트워크)와의 상호 작용을 중지하고 해당 계정을 사용하여 일부 공용 네트워크와 상호 작용하기 시작합니다.!!

    일반적으로 공용 네트워크와 상호 작용할 때 가장 먼저해야 할 일은 해당 네트워크의 에테르 중 일부를 확보하는 것입니다. 우리의 경우에는 Ropsten 공용 테스트 네트워크에 연결할 것이므로 Ropsten ether (ETH)를 구해야합니다! 걱정하지 마세요. 테스트 넷 ETH는 무료이며 풍부하며 획득하기가 매우 쉽습니다. &# 128077;

    테스트 ETH 획득 시간

    Ropsten ETH를 얻으려면 Ropsten 수도꼭지. 계정 주소를 붙여넣고 비올라! Ropsten ETH를 일부 받았으며 Ropsten 네트워크에 트랜잭션 전송 (즉, 상태 변경)을 시작할 수 있습니다.!

    참고로 Ropsten 테스트 네트워크는 공용 이더 리움 테스트 네트워크로, 이더 리움 메인 넷의 환경과 거의 유사한 환경에서 코드를 테스트 할 수 있습니다. Ropsten 테스트 넷 (및 다른 공개 이더 리움 테스트 넷)의 주요 차이점은 테스트 넷 랜드에서 ETH가 풍부하고 실제 가치가 없다는 것입니다! Ethereum 메인 넷과 상호 작용을 시작하면 거래 비용 (가스 비용)을 지불하는 데 사용하는 Ether에 실제 달러가들 것입니다. 따라서 우리가 열심히 일을하도록 미리 확인해야합니다. -적립 된 현금 / 우리의 소중한 메인 넷 ETH!

    Ropsten 테스트 네트워크는 대부분의 다른 공용 테스트 네트워크와 함께 체인에서 발생하는 활동을 볼 수있는 많은 블록 탐색기가 있습니다 (https://ropsten.etherscan.io/). 자금이있는 계정을 보려면 계정의 주소를 탐색기에 붙여 넣기 만하면됩니다. 그러면 해당 계정과 관련된 모든 내역을 볼 수 있습니다.

    스크린 샷 2020 09 01 at 4 34 21 AM

    좋구나! 이제 지갑 공급자와 Ropsten ETH로 자금을 조달 한 계정을 얻었으므로 프로젝트로 돌아가서 Ropsten 테스트 네트워크에 연결된 Infura 노드를 가리킬 수 있습니다..

    가장 먼저해야 할 일은 소중한 비밀을 보관할 .env 파일을 만드는 것입니다! 이러한 비밀에는 Infura API 키 (Infura 계정을 만들 때 생성됨)와 니모닉 문구가 포함됩니다..

    프로젝트의 루트 수준에서 새 파일 “.env”를 생성하면됩니다. 또한 터미널에 다음 명령을 입력하여 dotenv NPM 패키지를 설치해야합니다.

    npm 설치-dotenv 저장

    이 new.env 파일에는 다음 두 가지가 필요합니다.

    INFURA_API_KEY = 여기에 API 키 삽입 (인용문 없음)

    MNEMONIC =”렌즈 고래 팬 와이어 버블 온라인 좌석 재고 번호 문장 당첨자 노출”

    INFURA_API_KEY는 이전에 infura에서 만든 프로젝트의 프로젝트 ID입니다.

    스크린 샷 2020 09 01 at 4 37 12 AM

    MNEMONIC은 이전에 계정을 생성 할 때 사용한 12 단어 시드 문구입니다..

    이제 파일이 다음과 같이 표시됩니다.

    스크린 샷 2020 09 01 at 4 41 53 AM

    좋아, 우리는 가까워지고있다!

    참고 : 이것을 Github 저장소로 푸시하거나 어떤 식 으로든이 프로젝트를 공개하려면 비밀이 노출되지 않도록 .env 파일을 .gitignore에 두어야합니다.! 

    이제 truffle-config.js 파일로 이동해야합니다. 여기에서 공급자 (이전에 설치 한 Truffle HDWallet 공급자)와 상호 작용하는 데 사용되는 공급자 (이전에 설치 한 Truffle HDWallet 공급자)를 나타내는 몇 가지 항목을 추가하고 앱을 Ropsten Infura 노드에 지정해야합니다..

    파일 맨 위에 다음을 추가하십시오.

    필요 ("Dotenv") .config (); const HDWalletProvider = require ("@ truffle / hdwallet- 제공자");

    다음으로 ‘네트워크’에서 다음 네트워크를 추가 할 수 있습니다.

    ropsten : {공급자 : () => new HDWalletProvider (process.env.MNEMONIC,`https://ropsten.infura.io/v3/$ {process.env.INFURA_API_KEY}`), network_id : 3, // Ropsten의 ID 가스 : 5500000, // Ropsten은 메인 넷 확인보다 낮은 블록 제한 : 2, // 배포 사이에 대기 할 conf 수. (기본값 : 0) timeoutBlocks : 200, // 배포 시간이 초과되기 전 블록 수 (최소 / 기본값 : 50) skipDryRun : true // 마이그레이션 전에 드라 이런을 건너 뛰시겠습니까? (기본값 : 공용 넷의 경우 false)}

     

    이제 truffle-config.js 파일은 다음과 같습니다.!

    참고 :

    Infura 엔드 포인트를 사용하는 경우 지갑이 없으므로`from` 매개 변수가 필요합니다. Ganache 또는 Geth RPC 끝점을 사용하는 경우 이는 선택적 매개 변수입니다..

    스크린 샷 2020 09 01 at 4 50 54 AM

    이제 우리는 마법에 대한 준비가되었습니다! ROPSTEN에 스마트 계약을 배포 할 때입니다.!

    스마트 계약 설정

    견고성 설정

    먼저 배포 할 스마트 계약을 만들고 싶습니다! 이 가이드의 이전 섹션에서 개발 한 스마트 계약을 가져 오거나, 자신의 스마트 계약을 작성하거나, 다음 (매우 간단한) 샘플 계약을 사용할 수 있습니다.

    프라 그마 견고 함 >= 0.5.8; 계약 SimpleStorage {uint256 storedData; function set (uint256 x) public {storedData = x; } function get () public view returns (uint256) {return storedData; }}

    이 계약은 프로젝트의 “contracts”폴더에 “.sol”(Solidity) 파일로 생성되어야합니다 (이 시나리오에서는 SimpleStorage 계약 인 SimpleStorage.sol 파일을 생성했습니다.

    발판

    마이그레이션 설정

    다음으로 마이그레이션 파일을 설정해야합니다.!

    마이그레이션은 Ethereum 네트워크에 계약을 배포하는 데 도움이되는 JavaScript 파일입니다. 이러한 파일은 배포 작업 준비를 담당하며 배포 요구 사항이 시간이 지남에 따라 변경된다는 가정하에 작성됩니다. 프로젝트가 발전함에 따라 블록 체인에서 이러한 발전을 촉진하기 위해 새로운 마이그레이션 스크립트를 생성합니다. 이전에 실행 된 마이그레이션 내역은 특별한 마이그레이션 계약을 통해 온 체인에 기록됩니다. 그들에 대한 더 많은 정보를 찾을 수 있습니다 여기.

    계약을 배포하기위한 마이그레이션 파일은 다음과 같습니다.

    const SimpleStorage = artifacts.require ("SimpleStorage.sol"); module.exports = function (deployer) {deployer.deploy (SimpleStorage); };

    이 파일을 “2_deploy_contracts.js”라는 이름으로 “migrations”폴더에 저장합니다..

    첫 번째 공개 계약 배포

    마이그레이션 시간

    이제 실제로 마법이 일어날 준비가되었습니다! 콘솔로 돌아가서

    트러플 마이그레이션-네트워크 ropsten

    팔!&# 128163; 귀하의 코드는 공용 Ropsten Ethereum Test Net에 배포되었습니다.!!! 

    방금 일어난 일은 다음과 같습니다.

    1. Solidity 스마트 계약 ( “contracts”폴더에 있음)이 바이트 코드로 컴파일되었습니다 – 이더 리움 가상 머신이 사용할 기계 판독 가능 코드.

    2. 이 바이트 코드와 일부 다른 데이터는 하나의 트랜잭션으로 묶여 있습니다..

    3. 해당 거래는 귀하의 계정에 의해 서명되었습니다..

    4. 해당 트랜잭션은 Ropsten에 연결된 Infura 노드로 전송되었습니다..

    5. 트랜잭션은 네트워크 전체에 전파되고 Ropsten 채굴자가 선택하여 Ropsten 블록에 포함되었습니다..

    6. 귀하의 스마트 계약은 이제 Ropsten 블록 체인에 적용됩니다.!

    Etherscan을 사용하여 계약을 볼 수 있습니다. https://ropsten.etherscan.io/ – 계약서를 보려면 계약서 주소 (터미널에 있어야 함)를 붙여 넣기 만하면됩니다.!

    스크린 샷 2020 09 01 at 5 19 12 AM

    놀랄 만한! 우리는 PUBLIC Ethereum 네트워크에 첫 번째 스마트 계약을 배포했습니다.! &# 129327;

    이더 리움 메인 넷에 대한 truffle-config.js 파일의 네트워크를 교체한다는 점을 제외하면 이더 리움 메인 넷에 배포하는 과정은 똑같습니다 (물론 Ropsten 대신 메인 넷 Truffle 마이그레이션 명령을 실행합니다). ! 이더 리움 메인 넷에 배포하면 실제 비용이 들기 때문에 여기서는이 프로세스를 설명하지 않겠습니다.하지만 도움이 필요하면 다음 페이지로 이동하세요. ConsenSys Discord 기꺼이 도와 드리겠습니다.!

    Web3 프런트 엔드 구축 

    이제 Ropsten에 계약을 배포 했으므로 계약과 상호 작용할 수있는 간단한 사용자 인터페이스를 구축하겠습니다.!

    참고 : dApp “프론트 엔드”는 일상적인 기존 프런트 엔드 일뿐입니다. 따라서 익숙한 모든 기존 도구 (create-react-app 등)를 사용하여 프런트 엔드를 가동 할 수 있습니다. , 그런 다음 프런트 엔드가 Ethereum에서 읽고 쓸 수 있도록 몇 가지를 추가하십시오! 즉, 기존 웹 개발 기술은 모두 Ethereum-land / Web3로 직접 이전 할 수 있습니다.!!

    React 프로젝트 시작 

    알겠습니다. 시작하겠습니다..

    먼저 스토리지 계약을 위해 방금 만든 모든 정보가 포함 된 디렉토리가 있는지 확인하십시오. 내 폴더 이름을 “storage-back”으로 지정했으며 계약 설정 및 배포를 위해 방금 완료 한 작업이 포함되어 있습니다.. 

    스크린 샷 2020 09 01 at 5 26 33 AM

    이제 반응 프로젝트를 회전하는 것으로 시작하겠습니다.이 예제에서는 “storage-lab”이라고 부르겠습니다.

    터미널에서 다음을 실행하여 프로젝트를 시작하겠습니다. 

    npx create-react-app storage-lab

    이제 새 프로젝트 상용구가 준비되었으므로 프로젝트 디렉토리로 이동해 보겠습니다.

    CD 저장실

    이제 프로젝트 내부에 있으므로 프로젝트가 Ethereum과 상호 작용할 수 있도록 Web3 패키지를 추가합니다! web3에 대한 추가 정보 여기

    npm 설치 web3

    Web3는 우리가 사용할 수있는 두 가지 주요 패키지 중 하나이며 다른 하나는 ethers.js입니다. 이 예제에서는 web3을 사용할 것이지만 ethers.js에 대해 자세히 알아 보려면 여기 

    두 가지에 대한 자세한 설명은이 글을보세요. web3 대 에테르

    큰! 이제 리 액트 프로젝트가 계약과 상호 작용할 준비가 거의되었습니다.!

    먼저 스마트 계약과 관련하여 이미 수행 한 작업 만 포함 된 이전 디렉토리 (저는 “스토리지 백”)를 가져 와서 새 리 액트 프로젝트에 추가하겠습니다. 이것은 우리의 src와 같은 수준에있을 것이고, 이제 우리는 우리 반응 REPO 안에 필요한 모든 것을 가지고 있어야합니다..

    스크린 샷 2020 09 01 at 5 31 38 AM

    다음으로 ABI 정보가 포함 된 파일을 설정해야합니다..

    “ABI?”

    물어봐서 기뻐! 

    ABI (Contract Application Binary Interface)는 블록 체인 외부에서 그리고 계약 간 상호 작용을 위해 Ethereum 생태계 내의 계약과 상호 작용하는 표준 방법입니다. 이전 단계에서 SimpleStorage 계약을 컴파일했을 때 JSON 파일이 생성되었습니다. 직접 확인하세요. 빌드 / 계약 내에 SimpleStorage.json 파일이 있습니다.

    스크린 샷 2020 09 01 at 6 04 20 AM

    이 파일을 처음 살펴보면 많은 정보가 표시됩니다. 지금은 계약을 개발중인 프런트 엔드와 동기화하기 위해 ABI에만 집중하면됩니다. 이 JSON에는 프런트 엔드와 계약을 전달하는 데 필요한 정보가 포함되어 있습니다..

    ABI는 객체를 보유하는 배열입니다. 파일을 자세히 살펴보면 각 객체가 실제로 SimpleStorage 계약에 포함 된 각 기능임을 알 수 있습니다..

    스크린 샷 2020 09 01 at 5 33 23 AM

    빨리 볼 수 있습니다

    “이름”: “설정”

    “이름”:“가져 오기”

    둘 다 “유형 :”함수 “로 스마트 계약을 작성할 때 선언 한 두 함수 모두!

    Truffle은 다음 몇 단계를 난독 화하지만 모든 기본 사항에 노출 될 수 있도록 훨씬 더 “수동적 인”작업 방법을 살펴 보겠습니다. &# 128578;

    먼저 abi 정보를 복사하세요. 잠시 후에 필요합니다.. 

    src 안에 “abi”라는 폴더를 만들어 보겠습니다..

    새로 만든 abi 폴더 안에 abi.js라는 파일을 만들어 보겠습니다.

    참고 : 기술적으로 이러한 분리가 필요하지 않으며 abi.js를 src에 추가하기 만하면됩니다.하지만 abi.js 파일을 포함하면 정리하는 데 도움이됩니다..

    이제 SimpleStorage.JSON 파일에서 이전에 가져온 abi 배열을 복사하여 새로 만든 abi.js 파일에 추가합니다. 프로젝트가 정보를 App.js로 가져올 수 있도록 파일을 약간 변경합니다. 이 파일은 .js 파일이므로 나중에 app.js로 가져올 수 있도록 내보내기를 추가해야합니다. 카멜 케이스 (아래 코드 참조)를 제외하고 const 이름을 계약과 동일하게 지정하겠습니다.

    이것은 abi.js 파일에 저장하는 코드입니다.

    export const simpleStorage = [{상수 : false, 입력 : [{이름 : "엑스", 유형: "uint256", },], 이름 : "세트", 출력 : [], 지불 가능 : false, stateMutability : "지불 할 수없는", 유형: "함수", }, {상수 : 참, 입력 : [], 이름 : "가져 오기", 출력 : [{이름 : "", 유형: "uint256", },], 지불 가능 : false, stateMutability : "전망", 유형: "함수", },];

    App.js로 이동하여 web3과 새로 만든 abi.js 파일을 모두 가져올 시간입니다..

    또한이 예제에서 후크를 사용할 것입니다 (이것이 {useState}도 가져 오는 이유입니다. useState에 대해 자세히 읽을 수 있습니다. 여기.

    이제 App.js 파일의 상단이 다음과 같이 보일 것입니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 수입 "./App.css";

    이제 우리는 임의의 사용자가 지갑 공급자가있는 한 dApp에 연결하고 사용할 수있는 능력을 갖출 수 있는지 확인해야합니다.!

    디앱 상호 작용을 위해 이더 리움 공간에서 사용되는 메인 지갑은 1 단계에서 소개 한 메타 마스크입니다..

    MetaMask가없는 경우 다음을 방문하십시오. metamask.io

    MetaMask를 설치하면 다음과 같이 dapp 내부의 지갑에 액세스 할 수 있습니다.

    const web3 = new Web3 (Web3.givenProvider);

    “Web3.givenProvider”는 이더 리움 지원 브라우저에서 설정됩니다..

    (필요한 이유에 대해 자세히 읽을 수 있습니다. 여기)

    이제 코드는 다음과 같아야합니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 수입 "./App.css"; const web3 = new Web3 (Web3.givenProvider);

    확인! 지금까지 우리는 :

    • React 프로젝트 시작
    • Web3 설치
    • 빌드 + 계약 + 마이그레이션을 포함하는 폴더를 React 프로젝트에 추가했습니다.
    • SimpleStorage.json에서 가져온 abi 데이터를 보관하는 abi.js 파일을 생성했습니다.
    • 계약과 상호 작용하는 데 필요한 데이터를 가져 왔습니다.
    • dApp이 사용자의 지갑과 통신 할 수 있도록하는 변수 생성

    다시 말하지만, Truffle은 다음 몇 단계를 불필요하게 만들지 만 (나중에 훨씬 더 간단한 버전을 안내 할 것입니다) 교육 목적으로 dApp에 약간의 수동 복잡성을 추가 할 것입니다..

    이제 우리가 할 일은 두 개의 새로운 변수를 만드는 것입니다. 하나는 Ropsten에 배포 한 계약의 주소를 저장하고 다른 하나는 해당 계약을 ABI에 일치시켜 앱이 대화하는 방법을 알 수 있도록합니다.! 

    계약 주소를 찾으려면 이전에 있던 JSON 파일 (ABI (SimpleStorage.json) 포함)으로 이동하고 맨 아래로 스크롤합니다. 주소는 여기 “주소”필드에 있습니다.

    "컴파일러": { "이름": "solc", "버전": "0.5.8 + commit.23d335f2.Emscripten.clang" }, "네트워크": { "삼": { "이벤트": {}, "연결": {}, "주소": "0x24164F46A62a73de326E55fe46D1239d136851d8", "transactionHash": "0x1f02006b451b9e85f70acdff15a01c6520e4beddfd93a20e88a9b702a607a7b0" }}, "schemaVersion": "3.0.16", "updatedAt": "2020-06-30T20 : 45 : 38.686Z", "devdoc": { "행동 양식": {}}, "userdoc": { "행동 양식": {}}}

    또는 다음으로 이동할 수 있습니다. https://ropsten.etherscan.io/ 계약을 배포 한 계정의 주소를 찾아보세요! Etherscan에서 “Contract Creation”을 클릭하면 계약 주소 자체가 표시됩니다..

    스크린 샷 2020 09 01 at 5 43 46 AM

    이제 계약 주소의 사본을 가져 와서 저장할 새 변수를 만듭니다.. 

    이것이 없으면 우리는 계약과 의사 소통 할 수 없으며 dApp이 의도 한대로 작동하지 않습니다..

    const web3 = new Web3 (Web3.givenProvider); 아래에 추가합니다.

    const contractAddress = "여기에 귀하의 계약 주소";

    그런 다음 계약 주소 (앱이 계약 위치를 알 수 있도록)와 ABI (앱이 계약과 상호 작용하는 방법을 알고 있음)를 모두 포함하는 “storageContract”라는 또 다른 새 변수를 만듭니다..

    const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    이제 App.js가 다음과 같이 보일 것입니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 수입 "./App.css"; const web3 = new Web3 (Web3.givenProvider); const contractAddress = "여기에 귀하의 계약 주소"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    이제 계약 및 프런트 엔드와 상호 작용할 변수를 보유 할 후크를 가져와야합니다. 앱 함수 내에서 다음을 선언하여이를 수행합니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 수입 "./App.css"; const web3 = new Web3 (Web3.givenProvider); const contractAddress = "당신의 계약 주소"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const [number, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    useState (0)의 첫 번째 사용은 사용자가 선언 한 uint256을 유지합니다..

    (number, setUint, getNumber, setGet의 명명 규칙은 무슨 일이 일어나고 있는지 보여주기를 바랍니다)

    useState ( “0”) 값은 서명 된 작업 (우리가 선언 한 uint256)에 대한 확인을받을 때까지 자리 표시 자 역할을합니다.

    setUint 우리는 곧 반환 할 것입니다.

    논리를위한 시간

    다음으로 numberSet 및 NumberGet 로직을 추가합니다 (함수 앱 내에 numberSet 추가).

    const numberSet = 비동기 (t) => {t.preventDefault (); const 계정 = await window.ethereum.enable (); const 계정 = 계정 [0]; const gas = await storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from : account, gas,}); }; const numberGet = 비동기 (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    preventDefault를 설정했습니다 (preventDefault에 대한 세부 정보가 여기)

    또한 계약을 위해 get에서 비동기 호출을 사용합니다 (비동기에 대한 세부 정보가 여기)

    후크 setGet ()은 우리가 처음에 본 기본값 ( “0”)을 저장합니다.

    const 계정 = await window.ethereum.enable ();

    MetaMask를 통해 연결된 주소를 호출하고 있는지 확인합니다..

    const 계정 = 계정 [0];

    연결 계정을 가져옵니다.

    무슨 일이 일어나고 있는지 궁금 할 것입니다. 

    const gas = await storageContract.methods.set (number) .estimateGas ();

    Google 앱은 가스 요금, 테스트 넷 또는 메인 넷에 상관없이 이더넷을 요청하는 모든 기능을 지불하기 위해 사용자 자금에 액세스 할 수있는 권한이 필요합니다. 이것은 MetaMask에 대한 연결이 우리의 uint256을 설정하고 비용을 지불하기 위해이 사용에 서명하는 데 유용합니다 (테스트 ETH 사용)..

    따라서 가스가 필요한 모든 기능에 대해 사용되는 잠재적 가스를 계산해야합니다..

    계약의 “설정”기능에는 가스가 필요합니다.

    “Get”은.

    (이것은“Get”이“Set”로 이미 선언 된 것을보고 있기 때문입니다.)

    const post는 uint256에서 전달 된 정보를 가져와 Ropsten 네트워크의 MetaMask 지갑에서 거래 (가스 요금 지불 후)를 확인합니다..

    다음으로 methods.set ()을 통해 함수 매개 변수를 전달하고 선언 된 주소 (사용자 주소)로 Set 함수를 처리합니다..

    함수 매개 변수를 스마트 계약 methods.set ()에 전달하고 예상 가스 및 사용자 계정 주소를 .send ()에 전달하여 스마트 계약 트랜잭션을 생성합니다..

    const post = await storageContract.methods.set (number) .send ({from : account, gas,});

    이것은 numberSet을 처리하는 데 필요한 모든 로직이어야합니다..

    이제 우리는 우리의 번호가 필요합니다

    const numberGet = 비동기 (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    우리의 const 포스트는 우리가 선언 한 새로운 값으로 set 번호를 검색하고 setGet을 전달합니다.

    따라서 “0”은 onClick이 numberGet을 참조하고 unint256을 렌더링합니다.!

     이제 app.js는 다음과 같이 보일 것입니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 수입 "./App.css"; const web3 = new Web3 (Web3.givenProvider); const contractAddress = "당신의 계약 주소"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const [number, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = 비동기 (t) => {t.preventDefault (); const 계정 = await window.ethereum.enable (); const 계정 = 계정 [0]; const gas = await storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from : account, gas,}); }; const numberGet = 비동기 (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    가능한지 테스트 할 수 있도록 매우 기본적인 렌더링 반환 값을 만들어 보겠습니다. 

    • unint256 값 설정,
    • 메타 마스크 지갑을 열고 거래를 확인하세요.
    • 가스 비용 지불
    • 그런 다음 트랜잭션이 완료되면 저장 한 값 (unint256)을 가져옵니다..

    반환은 다음과 같습니다. 

    return (uint256 설정 : setUint (t.target.value)} /> 확인

    uint256 {getNumber} 가져 오기); } 기본 앱 내보내기;

    빠른 CSS

    이제 App.css 파일로 이동하여 상용구 코드를 삭제하고 대신 추가하겠습니다.

    .main {text-align : center; 디스플레이 : 플렉스; 정당화 내용 : 센터; 배경색 : # f2f1f5; 높이 : 100vh; } .card {최소 높이 : 50vh; 폭 : 50vw; 디스플레이 : 플렉스; 플렉스 방향 : 열; 정렬 항목 : 가운데; 정당화 내용 : 센터; } .form {높이 : 20vh; 폭 : 20vw; 디스플레이 : 플렉스; 정당화 내용 : 공간을 균등하게; 플렉스 방향 : 열; } .button {너비 : 20vw; 높이 : 5vh; }

    이제 테스트 할 준비가되었습니다.!

    터미널에서 실행

    원사 시작

    localhost : 3000에서 우리는 다음과 같이 보일 것입니다.

     

    스크린 샷 2020 09 01 at 6 12 49 AM

    이제 입력 필드에 unint256 값을 입력 할 수 있습니다.!

    dApp에서 번호를 확인한 후 MetaMask를 통해 서명합니다 (지갑이 Ropsten 네트워크로 설정되어 있는지 확인).

    confrim1

    우리는 해냈다! &# 129303;

    이제 우리는 스마트 계약을 프런트 엔드에 연결하고 Set 기능을 조작 할 수 있습니다 (거래에 대한 가스 요금을 지불 할 테스트 ETH가있는 경우). 그런 다음 Get 함수를 호출하고 저장된 uint265 값을 검색 할 수 있습니다..

    꽤 멋지다!?!

    추가 스타일링 

    이제 훨씬 더 인기있는 Web2 기술을 프로젝트에 쉽게 구현할 수 있는지 보여줄 때입니다..

    우리는 MUI를 사용하여 기본 스타일링을 추가 할 것입니다. 이미 React로 개발했다면 material-ui에 익숙 할 것입니다. (세부 정보 발견 여기) Material-UI 또는 줄여서 MUI는 명명 규칙을 따를 경우 많은 스타일링을 사용하여 프로젝트를 빠르게 시작할 수있는 매우 인기있는 React 프레임 워크입니다. 파운데이션 만 사용하고 거기에서 사용자 정의하려는 경우 조작하기도 매우 쉽습니다..

    * 이것은 Web2 기술과 함께 우리 프로젝트를 얼마나 빨리 통합 할 수 있는지를 보여주기 위해 작은 추가 사항으로 프로젝트에 MUI를 추가하는 방법에 대한 매우 짧은 예입니다.. 

    MUI 추가

    명령을 실행하여 시작합니다 (터미널의 프로젝트 디렉토리에있는 동안 (앱이 아직 실행중인 경우 닫거나 (ctrl + c)) 새 탭을 열어야 함).

    npm으로 설치하려면 :

    npm 설치 @ material-ui / core

    또는 원사로 :

    원사 추가 @ material-ui / core

    이제 MUI가 주입되었으므로 스타일 변경부터 시작하겠습니다. app.js 파일 맨 위에 몇 가지 새로운 항목을 가져올 것입니다.

    {simpleStorage} 가져 오기 "./ abi / abi"; 가져 오기 버튼 "@ material-ui / core / 버튼"; TextField 가져 오기 "@ material-ui / core / TextField"; import {makeStyles} from "@ material-ui / core / styles";

    {makeStyles} 가져 오기를 통해 기본 MUI 스타일 가져 오기와 함께 버튼 및 텍스트 필드의 스타일 (이 경우)을 조작 할 수 있습니다.. 

    이제 MUI에서 상용구 스타일을 가져 오는 변수 (함수 위에)를 만들 것입니다.

    const useStyles = makeStyles ((테마) => ({루트 : { "& > *": {여백 : theme.spacing (1),},},}));

    이제 App 함수 내에서 위에서 선언 한 정의 된 스타일을 가져 오는 “classes”라는 변수도 추가합니다..

    function App () {const 클래스 = useStyles (); const [숫자, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    이제 반환시 일부 필드를 방금 가져온 필드로 바꾸도록 조정합니다..

    return (setUint (t.target.value)} 변형 ="윤곽" /> 확인

    uint256 {getNumber} 가져 오기); } 기본 앱 내보내기;

    이제 코드는 다음과 같아야합니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 수입 "./App.css"; import {makeStyles} from "@ material-ui / core / styles"; 가져 오기 버튼 "@ material-ui / core / 버튼"; TextField 가져 오기 "@ material-ui / core / TextField"; const useStyles = makeStyles ((테마) => ({루트 : { "& > *": {여백 : theme.spacing (1),},},})); const web3 = new Web3 (Web3.givenProvider); const contractAddress = "여기에 귀하의 계약 주소"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const 클래스 = useStyles (); const [숫자, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = 비동기 (t) => {t.preventDefault (); const 계정 = await window.ethereum.enable (); const 계정 = 계정 [0]; const gas = await storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from : account, gas,}); }; const numberGet = 비동기 (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); }; return (setUint (t.target.value)} 변형 ="윤곽" /> 확인

    uint256 {getNumber} 가져 오기); } 기본 앱 내보내기;

    이제 반응 프로젝트를 살펴보면 다음과 같이 보일 것입니다.!

    스크린 샷 2020 09 01 at 6 48 55 AM

    잘 했어!

    우리는 여전히 이전의 모든 기능을 가지고 있으며 이제 우리가 원하는대로 프로젝트를 추가로 사용자 정의하기 위해 사용하기 쉬운 프레임 워크를 주입했습니다. MUI 살펴보기 선적 서류 비치 자신의 추가 / 수정 실험!

    보너스 라운드 

    사용자가 dApp 내에서 주소를 연결하는 것을 보여 주면 좋겠죠??

    이를 위해 매우 빠르고 기본적인 구성 요소를 만들어 보겠습니다.!

    App.js 파일로 다시 가져올 수있는 별도의 구성 요소를 만드는 것으로 시작합니다. App.js를 쉽게 탐색 할 수있을뿐만 아니라 이상적으로는 한 가지 작업 만 수행하는 구성 요소의 관행을 따르기 위해 논리를 분리하는 것이 좋습니다. 결국 성장하면 더 작은 하위 구성 요소로 분해되어야합니다..

    구성 요소 구축 

    src와 동일한 레벨에 components라는 새 폴더를 만들고 해당 폴더 내에 Nav.js 파일을 만듭니다. 이제 프로젝트 스캐 폴딩이 다음과 같이 보일 것입니다.

    스크린 샷 2020 09 01 at 6 47 07 AM

    또한 구성 요소 폴더 내에 Nav.css 파일을 만들어 Nav 구성 요소에 특별히 적용한 스타일을 가져옵니다..

    Nav.js를 열고 React, Web3 및 empty.css 파일을 가져 오겠습니다.

    React 가져 오기 "반응하다"; Web3 가져 오기 "web3"; 수입 "./Nav.css"

    이제 Nav라는 클래스를 만들고 여기에 몇 가지만 추가하여 연결된 주소를 표시합니다. 계정을 읽도록 상태를 설정하는 것으로 시작하겠습니다.

    class Nav extends React.Component {state = {계정 : "" };

    여전히 클래스 내에서 비동기 loadAccount 로직을 추가하여 읽을 계정을로드합니다.

    async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http : // localhost : 8080"); const 네트워크 = await web3.eth.net.getNetworkType (); const 계정 = await web3.eth.getAccounts (); this.setState ({계정 : 계정 [0]}); }

    다음으로 componentDidMount (컴포넌트 마운트 후 즉시 호출 됨)를 생성합니다.이 경우로드 된 계정을 가져옵니다. 더 읽어보기 여기

    componentDidMount () {this.loadAccount (); }

    참고 :

    이것은 다르게 수행 될 수 있습니다. 클래스 대신 함수를 만들고 componentDidMount와 반대되는 후크를 사용할 수 있지만이 예제에서는이 메서드를 고수합니다..

    그런 다음 리턴 위에 렌더를 생성합니다. render는 클래스 메소드를 사용하여 React 컴포넌트를 작성할 때 필요한 메소드입니다. 반환 내에서 p 태그와 함께 div에 주소 클래스를 추가 (나중에 기본 스타일 지정)하여 {this.state.account}를 사용하여 가져온 연결된 주소를 표시합니다.

    render () {return (연결된 주소 : {this.state.account}); }} 내보내기 기본 Nav;

    이제 Nav.js 파일이 다음과 같아야합니다.

    React 가져 오기 "반응하다"; Web3 가져 오기 "web3"; 수입 "./Nav.css" class Nav extends React.Component {state = {계정 : "" }; async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http : // localhost : 8080"); const 네트워크 = await web3.eth.net.getNetworkType (); const 계정 = await web3.eth.getAccounts (); this.setState ({계정 : 계정 [0]}); } componentDidMount () {this.loadAccount (); } render () {return (연결된 주소 : {this.state.account}); }} 내보내기 기본 Nav;

     

    Nav.css 파일로 이동하여 매우 기본적인 스타일을 추가하겠습니다.

    .주소 {디스플레이 : 플렉스; 정당화 내용 : 센터; }

    기술적으로는 이것을 App.css 파일에 추가 할 수 있습니다. 꽤 빨리 지저분해질 수 있음을 명심하십시오. 구성 요소는 재사용이 가능해야하며 작업을 구분하여 가능한 한 많은 마찰을 피하려면 길에서 두통을 줄일 수 있습니다..

    이제 App.js로 돌아가서 새로 만든 구성 요소를 가져 와서 반환에 추가하여 표시하도록하겠습니다.!

    완성 된 App.js 파일은 다음과 같습니다.

    import React, {useState} from "반응하다"; {simpleStorage} 가져 오기 "./ abi / abi"; Web3 가져 오기 "web3"; 다음에서 Nav 가져 오기 "./components/Nav.js"; 수입 "./App.css"; import {makeStyles} from "@ material-ui / core / styles"; 가져 오기 버튼 "@ material-ui / core / 버튼"; TextField 가져 오기 "@ material-ui / core / TextField"; const useStyles = makeStyles ((테마) => ({루트 : { "& > *": {여백 : theme.spacing (1),},},})); const web3 = new Web3 (Web3.givenProvider); const contractAddress = "여기에 주소"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const 클래스 = useStyles (); const [숫자, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = 비동기 (t) => {t.preventDefault (); const 계정 = await window.ethereum.enable (); const 계정 = 계정 [0]; const gas = await storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from : account, gas,}); }; const numberGet = 비동기 (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); }; 반환 ( setUint (t.target.value)} 변형 ="윤곽" /> 확인

    uint256 {getNumber} 가져 오기); } 기본 앱 내보내기;

    이제 연결된 주소를 맨 위에 표시하고 모든 기능을 유지해야합니다.!

    bonusV1

    &# 127881; 우리는 해냈다! &# 127881;

    이제 우리는 처음부터 구축 한 dApp이 있습니다. 우리는 스마트 계약을 React 프로젝트로 가져오고, 사용자 기능이 있는지 확인하는 로직을 작성하고, 연결된 주소를 렌더링하는 구성 요소를 만들었으며, 인기있는 스타일링 프레임 워크를 프로젝트에 추가했습니다..

    잘 했어! 이것은 Web3 개발 모험의 시작일 뿐이며 이미 만들었을뿐만 아니라 머리를 감싸고 있다는 것을 보여줄 무언가가 이미 있습니다. Discord에서 우리에게 연락하고 프로젝트를 공유하십시오 (특히 수정 또는 추가 한 경우).!

      개발자 온 보딩 : 1 단계개발자 온 보딩 1 단계

      개발자 온 보딩 : 1 단계

      개발자 온 보딩 : 2 단계개발자 온 보딩 2 단계

      개발자 온 보딩 : 2 단계

      10 분 이더 리움 오리엔테이션10 분 이더 리움 오리엔테이션

      10 분 이더 리움 오리엔테이션

    Mike Owergreen Administrator
    Sorry! The Author has not filled his profile.
    follow me