Quick Start

Step 1: Henesis CLI ์„ค์น˜ํ•˜๊ธฐ

Henesis CLI ์„ค์น˜โ€Œ

npm install -g @haechi-labs/henesis-cli

Henesis ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ

henesis login

Step 2: ์ƒ˜ํ”Œ ์ฝ”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ

Klaytn ์ƒ˜ํ”Œ ์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ์„œ ํ™•์ธํ•ด๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Sample Repository๋ฅผ ํ†ตํ•ด ์–ด๋–ป๊ฒŒ ๋ธ”๋ก์ฒด์ธ ํŠธ๋žœ์žญ์…˜์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

Sample Repository ๊ฐ€์ ธ์˜ค๊ธฐ

git clone https://github.com/HAECHI-LABS/sample-ethereum-tx-tracker

Sample ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™

cd sample-ethereum-tx-tracker

Dependency ์„ค์น˜

npm install

Step 3: ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ๋ณ€ํ™” ๊ตฌ๋… ์„ค์ •ํ•˜๊ธฐ

ํ™˜ ์„ค์ •ํ•˜๊ธฐ

Henesis๋ฅผ ํ†ตํ•ด ํŠธ๋žœ์žญ์…˜์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ตฌ๋…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ •๋ณด๋“ค์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • CLIENT_ID : henesis account:describe ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • PRIVATE_KEY : ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ง€๊ฐ‘์˜ ํ”„๋ผ์ด๋น— ํ‚ค์ž…๋‹ˆ๋‹ค. ์ถฉ๋ถ„ํ•œ ์–‘์˜ ์ด๋”๋ฆฌ์›€์ด ์žˆ๋Š” EOA ์ฃผ์†Œ์˜ ํ”„๋ผ์ด๋น— ํ‚ค๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. (ํ”„๋ผ์ด๋น— ํ‚ค ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•)

  • NODE_ENDPOINT : ์—ฐ๊ฒฐํ•  ๋ธ”๋ก์ฒด์ธ ๋…ธ๋“œ endpoint ์ž…๋‹ˆ๋‹ค.

  • PLATFORM : ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ตฌ๋…ํ•  ํŠธ๋žœ์žญ์…˜์˜ ํ”Œ๋žซํผ (ex. ethereum, klaytn)

  • NETWORK : ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ตฌ๋…ํ•  ํŠธ๋žœ์žญ์…˜์˜ ๋„คํŠธ์›Œํฌ (ex. ropsten, baobab)

ClientId๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ CLI ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

henesis account:describe
Email: haechi@haechi.io
Name: haechi
Organization: haechi-labs
ClientId: <YOUR-CLIENT-ID>

์„ค์ •ํŒŒ์ผ์ธ .env ์— ClientId ๋ฐ Private Key์™€ Node Endpoint๋ฅผ ๊ธฐ์ž…ํ•ด์ค๋‹ˆ๋‹ค.

CLIENT_ID=<YOUR-CLIENT-ID>
PRIVATE_KEY=<YOUR-PRIVATE-KEY>
NODE_ENDPOINT=https://tn.henesis.io/ethereum/ropsten?clientId=<YOUR-CLIENT_ID>
PLATFORM=ethereum
NETWORK=ropsten

TransactionTracker ์ƒ์„ฑํ•˜๊ธฐ

CLIENT_ID ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ๋ณ€ํ™” ๊ตฌ๋…์„ ์œ„ํ•œ TransactionTracker ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

quickstart.js
quickstart.js
const {TransactionTracker} = require('@haechi-labs/henesis-sdk-js');
...
const {CLIENT_ID, PRIVATE_KEY, NODE_ENDPOINT, PLATFORM, NETWORK} = process.env;
...
const tracker = new TransactionTracker(CLIENT_ID, {
platform: PLATFORM,
network: NETWORK
});

์ง€์›ํ•˜๋Š” ๋ธ”๋ก์ฒด์ธ ๋ชฉ๋ก์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ๋ณ€ํ™” ๊ตฌ๋…ํ•˜๊ธฐ

subscription ์„ ์ด์šฉํ•ด ์ถ”์ ํ•œ ํŠธ๋žœ์žญ์…˜์˜ ์ƒํƒœ๋ฅผ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • message.data.type ์—์„œ ์ถ”์ ํ•œ ํŠธ๋žœ์žญ์…˜์˜ ์ƒํƒœ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • message.ack() ๋ฅผ ๋งˆ์ง€๋ง‰์— ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

quickstart.js
quickstart.js
async function trackTx () {
const subscription = await tracker.subscribe(
'transaction',
{
subscriptionId: 'your-subscription-id',
ackTimeout: 30 * 1000 // ๊ธฐ๋ณธ๊ฐ’: 10 * 1000 (ms)
}
);
โ€‹
subscription.on('message', async (message) => {
console.log(`now transaction status is: ${message.data.type}`);
switch(message.data.type) {
case 'pending' :
// trackTransaction ํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ ์„ค์ •ํ•œ timeout์ด ์ง€๋‚ฌ์„ ๋•Œ
console.log('message.data.result',message.data.result);
break;
case 'receipt' :
// transaction์ด ์ฑ„๊ตด๋  ๋•Œ
console.log('message.data.result',message.data.result);
break;
case 'confirmation' :
// transaction์ด ์ฑ„๊ตด๋œ ํ›„ 'confirmation'๊ฐœ์˜ ๋ธ”๋ก์ด ์ถ”๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ
console.log('message.data.result',message.data.result);
break;
}
message.ack();
});
โ€‹
subscription.on('error', async (error) => {
console.log('err',error)
});
}

ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ๋ณ€ํ™” ์ถ”์ ํ•˜๊ธฐ

trackTransaction ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ถ”์ ํ•˜๊ณ  ์‹ถ์€ ํŠธ๋žœ์žญ์…˜์˜ txHash ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  • txHash ๋ฅผ trackTransaction ์— ๋„ฃ์–ด ์ถ”์ ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • timeout 30์ดˆ, ๊ทธ๋ฆฌ๊ณ  confirmation ์€ 6๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

ํŠธ๋žœ์žญ์…˜์ด ์ƒ์„ฑ๋˜๊ณ  ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋Š” ์ƒํ™ฉ์„ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Sender ๋ชจ๋“ˆ์„ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. Sender๋Š” ์ž…๋ ฅํ•˜์‹  ํ”„๋ผ์ด๋น— ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ์ฃผ์†Œ๊ฐ€ ์ž๊ธฐ ์ž์‹ ์—๊ฒŒ ํŠธ๋žœ์žญ์…˜์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ชจ๋“ˆ์ด๋ฉฐ ๊ฐ€์Šค๋น„ ์ด์™ธ์˜ ์ด๋”๋Š” ์†Œ๋ชจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์›์น˜ ์•Š์œผ์‹ ๋‹ค๋ฉด ์ž„์˜์˜ txHash๋ฅผ ์ž…๋ ฅํ•˜์‹ญ์‹œ์˜ค.

quickstart.js
quickstart.js
const {CLIENT_ID, PRIVATE_KEY, NODE_ENDPOINT, PLATFORM, NETWORK} = process.env;
const TIMEOUT = 30*1000;
const CONFIRMATION = 6;
...
const sender = new Sender(PRIVATE_KEY, NODE_ENDPOINT);
โ€‹
async function generateTx() {
const nonce = await sender.getNonce();
const txHash = await sender.send(nonce, GAS_PRICE);
console.log(`transaction generated. txHash:${txHash}`);
โ€‹
// transaction ํŠธ๋ž˜ํ‚น์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
// txHash๋Š” web3๋กœ ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ etherscan์—์„œ ์ž„์˜์˜ txHash๋ฅผ ๊ฐ€์ ธ์˜ค์…”๋„ ๋ฉ๋‹ˆ๋‹ค.
await tracker.trackTransaction(txHash, {
timeout: TIMEOUT,
confirmation: CONFIRMATION
});
}

Step 4: ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ๋ณ€ํ™” ํ™•์ธํ•˜๊ธฐ

์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํŠธ๋žœ์žญ์…˜์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

quickstart.js
quickstart.js
async function main () {
await trackTx();
await generateTx();
}
$ node quickstart.js

ํŠธ๋žœ์žญ์…˜์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ™”ํ•˜๊ณ  ๋ฉ”์„ธ์ง€๊ฐ€ ์ „๋‹ฌ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ •๋ณด๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

now transaction status is: receipt
message.data.result { blockHash:
'0x1328a899d25d873b12836f6faa6e28df45aeafcd2cf2c4984e2a157cfeb3b69a',
blockNumber: 6706349,
contractAddress: null,
cumulativeGasUsed: 21004,
from: '0x453011a4f948b22762290c1f4de3e2210c311c06',
gasUsed: 21004,
logs: [],
logsBloom:
'0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
status: true,
to: '0x453011a4f948b22762290c1f4de3e2210c311c06',
transactionHash:
'0xac1ad6d9f04161c2a4bbc0327a7a3a6a9bced4c5da9ff8752a3774fd98c51e7b',
transactionIndex: 0 }