[solidity Ganache-cli web3 solc] smart Contract 만들어 배포하기
본문 바로가기
Block Chain

[solidity Ganache-cli web3 solc] smart Contract 만들어 배포하기

by 쏠수있어ㅤ 2022. 2. 21.
반응형

npm init -> node 환경 만들어주기 

npm install ganache --global   / npm install -g ganache-cli 

npm install web3

npm install -g truffle

npm install solc

 

 

0. new 프로젝트 "ethereumdapp" 폴더 생성 > "contracts" 폴더 생성 > NotarizedDocument.sol 파일 생성 

NotarizedDocument.sol 파일에 아래 코드 작성

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

contract NotarizedDocument {

    mapping (bytes32 => bool) documentProof;

    function notarize(string memory document) public {
        bytes32 signedDocument = signDoc(document);
        storeDocumentProof(signedDocument);
    }

    function signDoc(string memory document) private pure returns (bytes32) {
        return sha256(abi.encodePacked(document));
    }

    function storeDocumentProof(bytes32 signedDocument) private {
        documentProof[signedDocument] = true;
    }

    function checkDocument (string memory document) public view returns (bool) {
        bytes32 signedDocument = signDoc(document);
        return hasProof(signedDocument);
    }

    function hasProof(bytes32 signedDocument) private view returns (bool) {
        return documentProof[signedDocument];
    }
}

 

1. node 시작하기 

npm init

 

 

2. ganache-cli 가상의 서버 돌리기

ganache-cli    // -> 사용할 test용의 accounts 계좌의 공개키/비밀키가 10개씩 나온다. + 서버 돌리기 

 

 

3. solidity 파일 컴파일해서 .bin .abi 파일 얻기

solcjs --bin --abi NotarizedDocument.sol    // -> solc가 solidity 파일을 컴파일하여 .bin .abi 파일을 생성한다. 

* abi = Application Binary Interface : 응용 프로그램 이진 인터페이스 - 응용 프로그램과 OS 또는 응용 프로그램과 해당 라이브러리, 또는 응용 프로그램의 구성 요소 간에 사용되는 낮은 수준의 인터페이스 

* bin = Binary file - 컴퓨터가 사용하는 이진 텍스트 파일 

 

 

4. contract 배포하기위해 node를 이용하여 node console에서 bytecode, api 얻기

아래 명령어 터미널에 입력

$ node   // node를 먼저 입력 -> welcome 뜨는 걸 확인 후 아래 명령어 입력
>bytecode=fs.readFileSync('NotarizedDocument_sol_NotarizedDocument.bin').toString()

위 명령어를 입력하면 function> 이 나오는데 아무 글자 써서(맞는지는 모르겠으나) Welcom to Node.js가 뜨고 그 다음에 아래 명령어 실행해야한다. 

bytecod라는 변수에 fs (file system) 모듈의 readFileSync()라는 함수를 사용하여 위에서 컴파일하여 나온 bin 파일을 넣고 toString() 문자열로 바꾼 값을 담는다. 아래처럼 쭉 나온다.

 

> abi=JSON.parse(fs.readFileSync('NotarizedDocument_sol_NotarizedDocument.abi').toString())

* 위에서 ">"는 제외

여기서도 abi라는 변수에 오른쪽 값을 담아준다. 이번에는 JSON.parse로 .abi파일을 읽어 만든 문자열을 다시 객체로 변환한 값이다. 

 

그러면 아래와 같은 두 개의 함수 (checkDocument, notarize)가 나온다. public으로 선언된 함수만 나옴 

abi와 bytecode가 있으면 이제 ganache-cli 계좌 중 하나에 배포할 수 있다. 

abi, bytecode 변수에 값이 잘 담겼는지 한번씩 해당 변수를 입력해서 값이 출력되는지 확인하기 

abi
bytocode

 

 

 

 

5. web3를 ganache와 연결하기 

현재 ganache는 (localhost:8545) 실행 중인 상태 (서버가 돌아가고 있음) command by "ganache-cli"

> Web3 = require('web3')
> web3 = new Web3("http://localhost:8545")

 

cannot find module 'web3' 오류가 나오면  터미널로 돌아가 web3 설치

npm install web3 // 설치해주기

 

6. notorizedContract 생성 및 deploy 배포하기 

notorizedContract = new web3.eth.Contract(abi)
> notorizedContract.deploy({data:bytecode})
.send({
from:'0x19e39a220bd0b32f3d0e6a01af0f2e9fc4697129',
gas:1500000,
gasPrice:web3.utils.toWei('0.00003', 'ether')})
.then((newContractInstance) => {notorizedContract.options.address=newContractInstance.options.address});

* bytecode 값이 undefined 라고 나오면 

위에 4번에 bytecode 값 선언 부분이 안된 것이니 한번 더 실행해준다. 

 

 

=> 값이 promise pending으로 나온다. 

Promise {
  <pending>,
  [Symbol(async_id_symbol)]: 4790,
  [Symbol(trigger_async_id_symbol)]: 4784,
  [Symbol(destroyed)]: { destroyed: false }
}

찾아보니 JavaScript로 promise를 먼저 만들고 Promise가 모두 처리되면 결과를 준다고 한다. 

성공하면 notorizedContract.options안에 address 를 넣게되는데 이걸 확인해보니 뭔가 address가 입력되긴 했다. 

 

하지만원래 나와야하는 모양새(?) 는 아래와 같다. 

Transaction: 0xb9c81c00b262878712af3803aba20f00562842a490c1dfc72610796b3fb00f4d
  Contract created: 0x350725ed3bbb91fa64745538f2d28dd0b4375f16
  Gas usage: 297522
  Block Number: 1
  Block Time:<>

 

일단은 배포하는 것부터 해보려고 return 값을 "hello there"로 하는 public function을 추가했다. 

 

NotarizedDocument.sol 파일 

.
.
.
    function hasProof(bytes32 signedDocument) private view returns (bool) {
        return documentProof[signedDocument];
    }

    function sayHello() public pure returns (string memory) {
        return "Hello there";
    }
}

그리고 위의 3번 - complie하는 부분부터 다시 반복 ! 

만든 notorizedContract 안의 methods들 (public으로 선언된 3개의 함수들) 중 sayHello()를 실행시키고 성공하면 console.log하기

notorized -&gt; notarized여야하는데 오타!

성공!

다른 블로거의 글도 위처럼 Pending이 떠있고 그다음에 결과가 나왔는데 

Transaction이 뜨는 결과는 왜 안나오는지 아직 모르겠다.

알게 되면 이어서 적어야겠다. 

 

 

-> 함수들 중 notarize()를 이용해서 블록 만들어보기는 성공했다. 

> notarizedContract.methods.notarize("Hello Romil!!").send({from:'0x19e39a220bd0b32f3d0e6a01af0f2e9fc4697129'}).then((f) => console.log(f))

// from: '주소' 는 ganache-cli 의 공개 주소 중 하나 아무거나 쓰면 된다. 

결과는 



성공 ! blockNumber:6인걸로 보아 위에서 pending뜬 것들이 계속 생성되었던듯 하다. 

hash 가 나오고 사용된 gas(수수료)도 얼만지 나온다. 

 

 

 

 

 


 

 

 

 

References : 

https://medium.com/coinmonks/get-started-with-building-ethereum-dapps-and-smart-contracts-d86b9f7bd1c

 

Creating & Deploying a Smart Contract using Web3js & Ganache-CLI — Part 1

Note — This article is updated with the latest version of Truffle, Solidity, Metamask, web3js, and Ganache-CLI

medium.com

https://medium.com/0xcode/interacting-with-smart-contracts-using-web3-js-part-ii-c1ef7566d1c5

 

Interacting With Smart Contracts Using Web3.js (Part II)

This is a continuation from Part I.

medium.com

 

반응형

댓글