Ethereum 개발 프레임워크 - Truffle의 기본 사용

트뤼플

트러플 소개

truffle unbox webpack 명령은
필요한 많은 모듈을 다운로드하는 데 약 10분이 걸리므로 먼저 Truffle을 살펴보겠습니다.

Truffle은 현재 가장 대중적인 이더리움 DApp 개발 프레임워크(공식 웹사이트 기준)이며,
세계 최고 수준의 개발 환경 및 테스트 프레임워크이자 EVM을 사용하는 모든 블록체인의 자산 관리 채널입니다. Ethereum에서 개발을 쉽게 만들 수 있습니다.

트러플에는 다음과 같은 기능이 있습니다.

 内置的智能合约编译,链接,部署和二进制文件的管理。
 合约自动测试,方便快速开发。
 脚本化的、可扩展的部署与发布框架。
 可部署到任意数量公网或私网的网络环境管理功能
 使用 EthPM 和 NPM 提供的包管理,使用 ERC190 标准。
 与合约直接通信的直接交互控制台(写完合约就可以命令行里验证了)。
 可配的构建流程,支持紧密集成。
 在 Truffle 环境里支持执行外部的脚本。

트러플 클라이언트

우리가 나중에 작성하는 스마트 계약은 테스트를 위해 체인에 배포되어야 하므로 트러플이 구축한 DApp
도 배포할 체인을 선택해야 합니다. Rinkeby 또는 Ropsten과 ​​같은 일부 공개 테스트 체인에 배포하도록 선택할 수 있지만 배포 및 테스트 시간이 상대적으로 길고 가스 부족을 방지하기 위해 가짜 토큰을 얻는 데 일정 시간이 걸린다는 단점이 있습니다. 물론 DApp 출시의 공식 프로세스를 위해서는 여전히 스테이징(시뮬레이션 환경)을 사용하여 퍼블릭 체인을 테스트해야 합니다.

또 다른 방법은 개발 단계에서 일반적으로 선택되는 프라이빗 체인에 배포하는 것입니다. Truffle은 공식적으로
다음 두 클라이언트를 권장합니다.
 Ganache
 truffle 개발


truffle development는 기본적으로 Ganache의 명령줄 버전과 유사한 truffle의 내장 클라이언트입니다 . truffle 디렉토리에 bash를 입력하십시오.

>truffle develop

클라이언트를 열 수 있으며 ganache처럼 자동으로 10개의 계정을 생성합니다.
주의할 점은 truffle 개발에서 truffle 명령을 실행할 때 앞의
"truffle"을 생략해야 한다는 것입니다. 예를 들어 "truffle compile"은 "compile"만 입력하면 됩니다.

트러플 설치

geth를 시작한 다음 truffle을 설치해 보겠습니다.
truffle은 dapp을 매우 쉽게 구축하고 관리 할 수 있는 dapp 개발 프레임워크입니다 .

다음과 같이 npm을 사용하여 설치할 수 있습니다. truffle: >npm install -g truffle
그런 다음 빈 디렉토리를 만들고 아래에 트러플 프로젝트를 만듭니다.

>mkdir simple_voting_by_truffle_dapp
>cd simple_voting_by_truffle_dapp
>npm install -g webpack
>truffle unbox webpack

truffle init: 현재 디렉터리에서 비어 있는 새 트러플 프로젝트를 초기화합니다(프로젝트 파일에는
truffle-config.js 및 truffle.js만 있고 계약 디렉터리에는 Migrations.sol만 있고 마이그레이션 디렉터리에는 1_initial_migration.js만 있음).

트러플 언박스: 트러플 상자를 직접 다운로드합니다. 즉, 사전 구축된 트러플 프로젝트입니다.
언박싱 프로세스는 비교적 길고 완료 후에 다음 메시지가 표시되어야 합니다.

여기에 이미지 설명 삽입
여기 웹팩은 웹팩 빌드 프로세스를 기반으로 하는 공식 프로젝트 프레임워크(트러플 박스)입니다 .
더 많은 트러플 박스는 https://truffleframework.com/boxes 를 참조하세요.

프로젝트 생성

트러플 프로젝트가 초기화되면
전체 dapp을 실행하는 데 필요한 모든 파일과 디렉터리가 생성됩니다. webpack의 트러플 상자를 직접 다운로드하고 그 안의 디렉토리는 비슷합니다.

>ls
README.md contracts node_modules test 
webpack.config.js truffle.js app migrations 
package.json
>ls app/
index.html javascripts stylesheets
>ls contracts/
ConvertLib.sol MetaCoin.sol Migrations.sol
>ls migrations/
1_initial_migration.js 2_deploy_contracts.js

 app/ - 애플리케이션 파일이 실행될 기본 디렉토리. 여기에는 javascript 파일
및 CSS 스타일 파일에 대한 권장 디렉토리가 포함되지만 이러한 디렉토리를 사용하는 방법은 사용자가 결정합니다.
 계약/ - Truffle의 기본 계약 파일 저장 디렉토리.  migrations/ - 배포 스크립트 파일을 위한 저장 디렉토리
test/ - 테스트 애플리케이션 및 계약을 위한 테스트 파일 디렉토리 프로젝트 아래의 계약 디렉토리에서 ConvertLib.sol 및 MetaCoin.sol 파일을 삭제하십시오.

>rm contracts/ConvertLib.sol contracts/MetaCoin.sol

또한 프로젝트 디렉토리에서 truffle.js라는 구성 파일을 찾으십시오. 여기에는
네트워크 개발을 위한 구성이 포함되어 있습니다. 개인 체인과 ganache가 기본적으로 이 포트에서 실행되기 때문에 포트 번호를 7545에서 8545로 변경하십시오.

이주

마이그레이션 개념
마이그레이션 디렉토리의 내용을 이해하는 것이 중요합니다. 이러한 마이그레이션 파일은
블록체인에 계약을 배포하는 데 사용됩니다.

이전 프로젝트에서는 노드 콘솔에서 VotingContract.new를 호출하여 투표 계약을 블록체인에 배포했습니다. 앞으로는 더 이상 이 작업을 수행할 필요가 없으며 truffle은 모든 배포를 배포하고 추적합니다.

마이그레이션은 배포 요구 사항이 시간이 지남에 따라 변경된다는 가정 하에 배포 작업을 스테이징하는 JavaScript 파일입니다. 프로젝트가 성장함에 따라 체인의 계약 상태를 변경하기 위해 새 마이그레이션 스크립트를 만들어야 합니다. 모든 실행 마이그레이션 이력 기록은 특별한 마이그레이션 계약을 통해 체인에 기록됩니다.

첫 번째 마이그레이션 1_initial_migration.js는 마이그레이션
이라는 계약을 블록체인에 배포하고 배포한 최신 계약을 저장하는 데 사용됩니다. 마이그레이션을 실행할 때마다 truffle은 블록체인에서 가장 최근에 배포된 계약을 쿼리한 다음 아직 배포되지 않은 모든 계약을 배포합니다.

그런 다음 마이그레이션 계약의 last_completed_migration 필드를 업데이트하여 배포된 최신 계약을 가리킵니다.
항상 최신 상태인 last_completed_migration 열이 있는 데이터베이스 테이블로 간단히 생각할 수 있습니다 .

마이그레이션 파일의 이름 지정에는 특별한 요구 사항이 있습니다. 접두사는
마이그레이션이 성공적으로 실행되는지 여부를 표시하는 데 사용되는 숫자(필수)이고, 접미사는 가독성을 높이고 이해를 돕기 위한 설명적인 단어입니다.

artifacts.require()


스크립트 시작 부분에서 우리 는 노드에서 요구하는 것과 매우 유사한 트러플에게 배포 및 마이그레이션하려는 계약을 알려주기 위해 artifacts.require() 메서드를 사용 합니다. 그러나 최신 공식 문서에서는 파일 이름이 아닌 정의된 계약 이름을 전달해야 한다고 경고하고 있습니다. .sol 파일에는 여러 계약이 포함될 수 있기 때문입니다.

수출의 기능


마이그레이션 js의 내보내기 기능은 첫 번째 매개변수 로 배포자 개체를 수신해야 합니다 . 이 개체는 주로 배포 및 게시 과정에서 명확한 구문 지원을 제공하고 나중에 사용하기 위해 배포된 파일을 저장하는 것과 같은 몇 가지 일반적인 계약 배포 책임을 제공하는 데 사용됩니다.

배포자 개체

배포자 개체는 배포 작업을 준비하기 위한 기본 인터페이스입니다.
Truffle의 다른 모든 코드와 마찬가지로 Truffle은
자체 코드에 대한 계약 추상화를 제공하며 이더리움 네트워크와 쉽게 상호 작용할 수 있도록 초기화됩니다. 이러한 추상 인터페이스는 모두 배포 프로세스의 일부입니다.

마이그레이션 파일 업데이트

2_deploy_contracts.js의 콘텐츠를 다음 정보로 업데이트합니다.

var Voting = artifacts.require("./Voting.sol");
module.exports = function(deployer) {
    
    
deployer.deploy(Voting, ['Alice', 'Bob', 'Cary'], {
    
    gas:
290000});
};

위에서 볼 수 있듯이 배포자는 생성자 매개변수 다음에 오는 첫 번째 매개변수가 계약 이름일 것으로 예상합니다.

우리의 경우 후보 배열인 매개변수가 하나만 있습니다. 세 번째 매개변수는 코드를 배포하는 데 필요한 가스를 지정하는 데 사용하는 해시입니다. 가스의 양은 계약 규모에 따라 다릅니다. 투표 계약의 경우 290000이면 충분합니다.

트러플 구성 파일 업데이트

다음과 같이 truffle.js의 내용을 업데이트하십시오.

require('babel-register')
module.exports = {
    
    
networks: {
    
     
development: {
    
     
host: 'localhost', 
port: 8545, 
network_id: '*', 
gas: 470000 
} } }

이전 truffle.js와 업데이트된 파일의 유일한 차이점은 gas 옵션이라는 것을 알 수 있습니다.
모든 마이그레이션에 적용되는 전역 변수입니다. 예를 들어 2_deploy_contracts.js에서 가스 값을 290000으로 지정하지 않으면
마이그레이션은 기본적으로 470000으로 설정됩니다.

계약 코드 Voting.sol
은 이전에 코딩되었으며 추가 변경 없이 트러플에 사용할 수 있습니다.
simple_voting_dapp에서 계약 디렉토리로 파일을 복사하기 만 하면 됩니다.

계정 생성(메타마스크에서 계정 이전을 사용할 수 있음)

계약을 배포하기 전에 일부 이더가 포함된 계정이 필요합니다. ganache 를 사용할 때
각 계정에 100개의 테스트 에테르가 있는 10개의 테스트 계정이 생성되었습니다
. 하지만 테스트넷과 메인넷의 경우 자체 계정을 만들고 이더를 넣어야 합니다.

이전 ganache 응용 프로그램에서는 단일 노드 콘솔을 시작
하고 web3 개체를 초기화했습니다. 트러플 콘솔을 실행하면 트러플이 우리를 위해 모든 것을 처리하고 우리는 web3 객체를 사용할 준비가 되었습니다. 이제 우리는
잔액이 0인 '0x95a94979d86d9c32d1d2ab5ace2dcc8d1b446fa1' 주소(다른 주소를 얻게 됨)를 가진 계정을 갖게 되었습니다.

 >truffle console
// Replace 'verystrongpassword' with a good strong password.
truffle(development)> 
web3.personal.newAccount('verystrongpassword') ' 0xbaeec91f6390a4eedad8729aea4bf47bf8769b15'
truffle(development)> 
web3.eth.getBalance('0xbaeec91f6390a4eedad8729aea4bf47bf8769b1
5')
{
    
     [String: '0'] s: 1, e: 0, c: [ 0 ] }
truffle(development)> 
web3.personal.unlockAccount('0xbaeec91f6390a4eedad8729aea4bf47
bf8769b15', 'verystrongpassword', 15000)

전개하다

이미 이더가 있는 경우 블록체인에 계약을 컴파일하고 배포할 수 있습니다. 아래에서 관련 명령을 찾을 수
있으며 모든 것이 잘되면 다음과 같은 출력이 나타납니다.

>truffle compile
Compiling Migrations.sol...Compiling Voting.sol...Writing 
artifacts to ./build/contracts
>truffle migrate
Running migration: 1_initial_migration.js
Deploying Migrations...
Migrations: 0x3cee101c94f8a06d549334372181bc5a7b3a8bee
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying Voting...
Voting: 0xd24a32f0ee12f5e9d233a2ebab5a53d4d4986203
Saving successful migration to network...
Saving artifacts...

계정이 여러 개인 경우 관련 계정이 잠겨 있지 않은지 확인하십시오. 기본적으로 첫 번째 계정
web3.eth.accounts[0]이 배포에 사용됩니다.

가능한 문제 및 해결 방법

  1. 가스가 부족하여 배포에 실패하면
    마이그레이션/2_deploy_contracts.js의 가스 계정을
    500000으로 늘려보십시오. 예: deployer.deploy(투표, ['라마', '닉', '호세'],
    {가스: 500000});
  2. 여러 계정이 있고 계정[0] 대신 계정을 선택하려는 경우 truffle.js에서 사용하려는 계정의 주소를 지정할 수 있습니다. network_id 뒤에
    'from: your address'를 추가 하면 truffle이 배포하고 상호 작용하기 위해 지정한 주소를 사용합니다.

배포가 잘되면 콘솔 및 웹 페이지를 통해 계약과 상호 작용할 수 있습니다.

새 JavaScript 파일 app/scripts/index.js 만들기

   // Import the page's CSS. Webpack will know what to do with it.
import "../styles/app.css";
// Import libraries we need.
import {
    
     default as Web3} from 'web3';
import {
    
     default as contract } from 'truffle-contract'
import voting_artifacts from '../../build/contracts/Voting.json'
var Voting = contract(voting_artifacts);
let candidates = {
    
    "Alice": "candidate-1", "Bob": "candidate-2", 
"Cary": "candidate-3"}
window.voteForCandidate = function(candidate) {
    
     
    let candidateName = $("#candidate").val(); 
    try {
    
     
        $("#msg").html("Vote has been submitted. The vote count 
        will increment as soon as the vote is recorded on the blockchain. 
        Please wait.") 
        $("#candidate").val("");
        Voting.deployed().then(function(contractInstance) {
    
     
            contractInstance.voteForCandidate(candidateName, 
            {
    
    gas: 140000,
            from:web3.eth.accounts[0]})
            .then(function() {
    
     
                let div_id = candidates[candidateName]; 
                return

                contractInstance.totalVotesFor
                .call(candidateName).then(function(v) {
    
     
                $("#" + div_id).html(v.toString()); 
                $("#msg").html(""); 
                }); 
            }); 
        }); 
    } catch (err) {
    
     
        console.log(err); 
    } 
}

$( document ).ready(function() {
    
     
    if (typeof web3 !== 'undefined') {
    
     
        console.warn("Using web3 detected from external 
        source like Metamask") // Use Mist/MetaMask's provider 
        window.web3 = new Web3(web3.currentProvider); 
    } else {
    
     
        console.warn("No web3 detected. Falling back to 
        http://localhost:8545. You should remove this fallback when you 
        deploy live, as it's inherently insecure. Consider switching to 
        Metamask for development. More info here: 
        http://truffleframework.com/tutorials/truffle-and-metamask"); 
        // fallback - use your fallback strategy (local node / hosted node 
        + in-dapp id mgmt / fail) 
        window.web3 = new Web3(new
        Web3.providers
        .HttpProvider("http://localhost:8545")); 
    }
    Voting.setProvider(web3.currentProvider); 
    let candidateNames = Object.keys(candidates); 
    for (var i = 0; i < candidateNames.length; i++) {
    
     
        let name = candidateNames[i]; 

        Voting.deployed().then(function(contractInstance) {
    
     
            contractInstance.totalVotesFor
            .call(name).then(function(v) {
    
     
            $("#" + candidates[name])
            .html(v.toString()); 
            }); 
        }); 
    }
});

7행: 투표 계약을 컴파일하고 배포할 때 truffle
은 빌드 디렉터리 아래의 json 파일에 abi 및 배포된 주소를 저장합니다. 우리는 전에 abi에 대해 논의했습니다. 이 정보를 사용
하여 투표 추상화를 시작합니다. 그런 다음 이 추상화를 사용하여 투표 계약의 인스턴스를 만듭니다.

14행: Voting.deployed()는 계약 인스턴스를 반환합니다. truffle에 대한 모든 호출은 약속을 반환합니다
. 이것이 우리가 모든 트랜잭션 호출에 then()을 사용하는 이유입니다.

콘솔 상호 작용은 새 콘솔을 다시 열어야 합니다.

>truffle console
truffle(default)> 
Voting.deployed().then(function(contractInstance) 
{
    
    contractInstance.voteForCandidate('Alice').then(function(v) 
{
    
    console.log(v)})})
{
    
     blockHash: 
'0x7229f668db0ac335cdd0c4c86e0394a35dd471a1095b8fafb52ebd76714
33156',
blockNumber: 469628,
contractAddress: null,
....
....
truffle(default)> 
Voting.deployed().then(function(contractInstance) 
{
    
    contractInstance.totalVotesFor.call('Alice').then(function(v) 
{
    
    console.log(v)})})
{
    
     [String: '1'] s: 1, e: 0, c: [ 1] }


트랜잭션 을 보내는 데 시간이 걸리기 때문에 voteForCandidate 메서드를 호출한 후 약간 기다려야 합니다
. ) 메서드 .call() 없이 직접 호출할 수도 있으며
트랜잭션이 전송되지 않습니다.

나가는 트랜잭션은 geth의 로그 출력 파일에서 찾을 수 있으며 테스트 네트워크에 연결되어 있으면
etherscan의 https://rinkeby.etherscan.io에서 쿼리할 수 있습니다.

truffle의 기본 gasPrice가 100GWei인 것을 볼 수 있는데, 고민이라면 truffle.js에서 변경하고 gasPrice: 1000000000을 추가하여 1GWei로 변경하고 truffle 콘솔을 다시 시작하여 적용하면 됩니다.

웹 상호 작용
콘솔에서 webpack으로 서버 시작:

>npm run dev

기본 포트는 8080입니다. 브라우저에서 localhost:8080을 방문하면 페이지를 볼 수 있습니다.
메타마스크가 설치되어 있으면 index.js가 자동으로 메타마스크를 감지하여 web3
공급자로 사용하므로 현재 연결되어 있는 네트워크로 메타마스크를 전환하는 데 주의를 기울여야 합니다.

추천

출처blog.csdn.net/david2000999/article/details/120472092