From 747c7079448b18d5a62c46ef15967caf332795c4 Mon Sep 17 00:00:00 2001 From: Lucy Oh <56earls@gmail.com> Date: Fri, 20 Dec 2024 14:26:47 +0900 Subject: [PATCH] =?UTF-8?q?Add:=20Node.js=EC=97=90=EC=84=9C=20=EC=8A=A4?= =?UTF-8?q?=EB=A7=88=ED=8A=B8=20=EC=BB=A8=ED=8A=B8=EB=9E=99=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EB=B8=94=EB=A1=9D=EC=B2=B4=EC=9D=B8=EC=97=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _posts/2024-12-20-smart-contract-nodejs.md | 305 ++++++++++++++++++ .../2024-12-20-smart-contract-nodejs/0.png | Bin 0 -> 32191 bytes .../2024-12-20-smart-contract-nodejs/1.png | Bin 0 -> 14100 bytes 3 files changed, 305 insertions(+) create mode 100644 _posts/2024-12-20-smart-contract-nodejs.md create mode 100644 assets/img/2024-12-20-smart-contract-nodejs/0.png create mode 100644 assets/img/2024-12-20-smart-contract-nodejs/1.png diff --git a/_posts/2024-12-20-smart-contract-nodejs.md b/_posts/2024-12-20-smart-contract-nodejs.md new file mode 100644 index 0000000..07568d4 --- /dev/null +++ b/_posts/2024-12-20-smart-contract-nodejs.md @@ -0,0 +1,305 @@ +--- +title: Node.js에서 스마트 컨트랙트를 블록체인에 입력하기 +date: 2024-12-20 9:51:00 +/-TTTT +categories: [Security, Blockchain] +tags: [security, blockchain, ethereum, solidity, nodejs] +math: true +--- + +## 작업 환경 + +> [외부 Application에서 Geth에 연결](https://5jisoo.github.io/posts/geth-external-access/) 에서 이어지는 내용입니다. (Node.js 및 Web3 설정) +{: .prompt-info} + +- masOS M1 +- Geth Version: 1.10.17-stable +- Solidity Version: 0.8.19+commit.7dd6d404.Emscripten.clang +- Node.js Version: v20.17.0 +- Web3 Version: v0.20.0 + +## Solidity + +다음과 같이 `showMsg()`라는 간단한 solidity 코드를 node.js를 통해 실행시켜볼 예정이다. + +``` +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +contract hello{ + string message = "Hello world!"; + function showMsg() public view returns (string memory){ + return message; + } +} +``` + +먼저, 이 솔리디티 파일을 컴파일 해주어 abi, bin 파일을 만들어 준다. + +```shell +% solcjs --abi --bin hello.sol +``` + +## Node.js + +Geth 콘솔에서 했던 작업을 그대로 Node.js 코드로 작성해보자. + +- 콘솔을 7326 포트를 사용하기에 localhost:7326으로 설정해주었다. +- 각각 `abi`, `bin` 변수에 `abi`파일, `bin`파일 내용을 저장한다. + +```javascript +const Web3 = require("web3"); +const web3 = new Web3(); +web3.setProvider(new web3.providers.HttpProvider("http://127.0.0.1:7326")); + +const abi = [ + { + inputs: [], + name: "showMsg", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, +]; +const bin = + "0x{bin파일}"; +``` + +## 계좌 잠금 해제 및 트랜잭션 전송 + +여기까지는 이전과 동일하다. + +그 다음 password를 사용하여 `eth.accounts[0]`의 잠금을 푼 뒤, 트랜잭션을 전송해야 한다.
+하지만, 잠금을 푸는 데는 오랜 시간이 걸린다..! + +```js +const result = web3.personal.unlockAccount(web3.eth.accounts[0], "1234"); +tx = web3.eth.sendTransaction({ + from: web3.eth.accounts[0], + data: bin, + gas: "470000", + }); +``` + +`unlockAccount()` 함수가 완전히 끝난 뒤에 `sendTransaction()` 함수가 실행될 수 있도록 `await` 키워드를 사용해주어야 한다. + +> [Promise](https://ko.javascript.info/promise-basics)와 [async/await](https://ko.javascript.info/async-await) 참고 문서 +{: .prompt-info} + +간단하게 Promise 객체는 **어떤 작업에 관한 상태 정보**를 갖고 있는 객체이다. 작업의 결과가 Promise 객체에 저장되어 해당 객체를 보면 작업의 성공/실패 여부를 알 수 있다. + +- 보통 시켜두고 언제 완료될지 모르는 로직(비동기 로직)을 Promise 객체에 작성한다. +- new Promise와 같이 객체가 생성되는 순간 바로 executor이라는 콜백 함수를 실행한다. + +```js +const unlock = new Promise((resolve) => { + const result = web3.personal.unlockAccount(web3.eth.accounts[0], "1234"); + resolve(result); +}); +``` + +위 코드 에서는 unlockAccount() 비동기 로직이 완료되면 `resolve(result);`를 호출하는 코드이다. + +그 뒤, sendTransaction은 이전의 promise가 끝날때까지 기다려야하므로, `await unlock;`이라는 키워드를 통해 기다려준다. + +다만 await는 async함수 내에서만 사용할 수 있으므로, 코드 전체를 async함수로 감싸주어야 한다. 따라서 아래 코드와 같이 `async input()` 함수로 감싸주어 코드를 작성해준다. + +```js +const Web3 = require("web3"); +const web3 = new Web3(); +web3.setProvider(new web3.providers.HttpProvider("http://127.0.0.1:7326")); + +const abi = [ + { + inputs: [], + name: "showMsg", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, +]; +const bin = + "0x{bin파일}}"; + +input(); + +async function input() { + const unlock = new Promise((resolve) => { + const result = web3.personal.unlockAccount(web3.eth.accounts[0], "1234"); + resolve(result); + }); + + await unlock; + + tx = web3.eth.sendTransaction({ + from: web3.eth.accounts[0], + data: bin, + gas: "470000", + }); +} + +``` + +## Receipt 확인하기 + +다음으로, 트랜잭션의 receipt 정보를 가져와서 contractAddress 값을 가져와야 한다. 이 내용은 아래의 코드와 같이 js로 작성할 수 있다. + +```js +web3.eth.getTransactionReceipt(tx); +``` + +하지만 그 전에! 트랜잭션 전송 후 **마이닝**을 통해 블록을 블록체인에 연결한 뒤에 receipt 값이 생기면 contractAddress값을 가져올 수 있다. + +> 블록이 블록체인에 연결되기 전에, receipt는 null이다. [참고: 블록 연결 상태 확인하기](https://5jisoo.github.io/posts/smart-contract-variable-update/#%EB%B8%94%EB%A1%9D-%EC%97%B0%EA%B2%B0-%EC%83%81%ED%83%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0) +{: prompt-tip} + +따라서 1초마다 receipt 값을 검사하여 null아닐때 address를 return하도록 작성할 예정이다. `setInterval()`함수를 사용하여 작성해보자. + +> [setInterval() 참고 자료](https://developer.mozilla.org/ko/docs/Web/API/Window/setInterval) +{: .prompt-info} + +setInterval의 매개변수는 다음과 같다. +- `func` : `delay`마다 실행되는 function +- `delay` : 타이머가 지정된 함수 또는 코드 실행 사이에 지연해야 하는 밀리초(1/1000초) 단위의 시간 +등등 + +따라서 +1. 1초마다 반복하여 +2. `web3.eth.getTransactionReceipt(tx);`이 null인지 확인하고, +3. null일 경우 기다린다는 로그를 출력하고, +4. null이 아닐 경우 contractAddress를 꺼내 로그를 출력하고, 타이머의 반복작업을 취소하는 + +코드를 작성해보자. + +```js +const waitForConfirmation = setInterval(() => { + const result = web3.eth.getTransactionReceipt(tx); + if (result) { + console.log(result.contractAddress); + clearInterval(waitForConfirmation); + } else { + console.log("Wait for confirmation ... "); + } +}, 1000); // 1sec +``` + +## 중간 확인 + +먼저 geth 콘솔을 외부 접근이 가능하도록 실행해주자. + +- `--allow-insecure-unlock` : 원격 잠금 허용 + +```shell +% geth --datadir "data" \ +--http \ +--http.addr "0.0.0.0" \ +--http.port "7326" \ +--http.api "web3,eth,personal,net" \ +--http.corsdomain "*" \ +--allow-insecure-unlock \ +--nodiscover console +``` + +그 뒤, node 코드를 실행시킨다. + +```shell +% node test.js +``` + +현재 js 코드는 다음과 같다. + +```js +const Web3 = require("web3"); +const web3 = new Web3(); +web3.setProvider(new web3.providers.HttpProvider("http://127.0.0.1:7326")); + +const abi = [ + { + inputs: [], + name: "showMsg", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, +]; +const bin = + "0x{bin파일}"; // 길어서 생략 + +input(); + +async function input() { + const unlock = new Promise((resolve) => { + const result = web3.personal.unlockAccount(web3.eth.accounts[0], "1234"); + resolve(result); + }); + + await unlock; + + tx = web3.eth.sendTransaction({ + from: web3.eth.accounts[0], + data: bin, + gas: "470000", + }); + + const waitForConfirmation = setInterval(() => { + const result = web3.eth.getTransactionReceipt(tx); + if (result) { + console.log(result.contractAddress); + clearInterval(waitForConfirmation); + } else { + console.log("Wait for confirmation ... "); + } + }, 1000); +} +``` + + +그 뒤, console에서 채굴을 시작하면?? + +```shell +> miner.start() +> miner.stop() +``` + +다음과 같이 contractAddress를 확인할 수 있다. + +![img](/assets/img/2024-12-20-smart-contract-nodejs/0.png){: w="500" }{: .shadow} +_정상 실행 확인 완료!_ + +## 스마트 컨트랙트 실행 + +geth에서 했던 방식과 동일하게 코드를 작성해준다. +- web3를 붙인다는 것만 기억해주면 됨. + +address는 위에서 얻은 contractAddress 값을 그대로 가져와주었다. + +```js +const Web3 = require("web3"); +const web3 = new Web3(); +web3.setProvider(new web3.providers.HttpProvider("http://127.0.0.1:7326")); + +const abi = [ + { + inputs: [], + name: "showMsg", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, +]; + +const address = "0x33c37da4443c10badc724830d4c51c561d54c2df"; + +const helloInterface = web3.eth.contract(abi).at(address); +console.log(helloInterface.showMsg.call()); +``` + +이렇게 작성하고, 실행하면? + +```shell +% node run.js +``` + +다음과 같이 `Hello world!`가 출력되는 것을 확인할 수 있다. + +![img](/assets/img/2024-12-20-smart-contract-nodejs/1.png){: w="400" }{: .shadow} +_정상 실행 확인 완료!_ diff --git a/assets/img/2024-12-20-smart-contract-nodejs/0.png b/assets/img/2024-12-20-smart-contract-nodejs/0.png new file mode 100644 index 0000000000000000000000000000000000000000..efe011987afc01861e65324369baa82974240d43 GIT binary patch literal 32191 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 literal 0 HcmV?d00001 diff --git a/assets/img/2024-12-20-smart-contract-nodejs/1.png b/assets/img/2024-12-20-smart-contract-nodejs/1.png new file mode 100644 index 0000000000000000000000000000000000000000..b28fd12f13e03d017dbd6698076595b9642936d5 GIT binary patch literal 14100 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