4-2. transaction 만들어서 보내기

동동주·2025년 10월 1일
  1. hardhat-ethers로 transaction 만들고 node 전송, 실행해보기
  2. 그냥 ethers로는 어떻게 하는지

1. hardhat-ethers에서 transaction 생성&실행

코드1

import hre from "hardhat";

describe("hardhat-test", async () => {
  it("hardhat ethers test", async () => {
    const signers = await hre.ethers.getSigners();
    // bob --> alice : 100ETH
    const bobWallet = signers[0];
    const aliceWallet = signers[1];
    const tx = {
      from: bobWallet.address,
      to: aliceWallet.address,
      value: hre.ethers.parseEther("100"),
      // 단위 변환 하는 거...
      // 1ETH == 1 * 10^18 wei
      // 100ETH == 100 * 10^18 wei
      // 10 ETH + 0.0000000001 ETH ==> wei 변환, 계산, 다시 ETH로 표시?
      // 정밀한 표현을 위해 wei를 사용한다~.
    };
    const txhash = await bobWallet.sendTransaction(tx);
    // txhash = (txid). 모든 tx 중에서 유일함 --> 추적 가능
    const receipt = await txhash.wait(); //기다렸다 영수증나오기
    console.log(await hre.ethers.provider.getTransaction(txhash.hash));
    console.log("----------------------");
    console.log(receipt);
  });
  it("ethers test", async () => {});
});

해당 코드1 작성 후 아래 코드 터미널에 작성하면 결과가 보인다

npx hardhat test //실행 시 터미널 출력 

터미널 1

출력내용

hardhat-test
TransactionResponse {
provider: HardhatEthersProvider {
_hardhatProvider: LazyInitializationProviderAdapter {
_providerFactory: [AsyncFunction (anonymous)],
_emitter: [EventEmitter],
_initializingPromise: [Promise],
provider: [BackwardsCompatibilityProviderAdapter]
},
_networkName: 'hardhat',
_blockListeners: [],
_transactionHashListeners: Map(0) {},
_eventListeners: []
},
blockNumber: 1,
blockHash: '0xeafc0b1bfe3788bf41a30f88710fd247cb4f606a845f0641774b1721173f8c57',
index: undefined,
hash: '0x09e8b0c12da97a8aec1e980aea71fec096e8a5b612e4b127a8522dcb7a0df9af',
type: 2,
to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
nonce: 0,
gasLimit: 30000000n,
gasPrice: 1875000000n,
maxPriorityFeePerGas: 1000000000n,
maxFeePerGas: 2750000000n,
maxFeePerBlobGas: null,
data: '0x',
value: 100000000000000000000n,
chainId: 31337n,
signature: Signature { r: "0x2bbb032852fe68ed03df5cc494c2da99b66a45865add072725627371bcb09aaa", s: "0x23ca2bb81e4b10f729f31f2888a21c3fd7ad5af2b5e3402133eb4d3e364d15e9", yParity: 0, networkV: null },
accessList: [],
blobVersionedHashes: null,
authorizationList: null

}

Promise {
TransactionReceipt {
provider: HardhatEthersProvider {
_hardhatProvider: [LazyInitializationProviderAdapter],
_networkName: 'hardhat',
_blockListeners: [],
_transactionHashListeners: Map(0) {},
_eventListeners: []
},
to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
contractAddress: null,
hash: '0x09e8b0c12da97a8aec1e980aea71fec096e8a5b612e4b127a8522dcb7a0df9af',
index: 0,
blockHash: '0xeafc0b1bfe3788bf41a30f88710fd247cb4f606a845f0641774b1721173f8c57',
blockNumber: 1,
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
gasUsed: 21000n,
blobGasUsed: undefined,
cumulativeGasUsed: 21000n,
gasPrice: 1875000000n,
blobGasPrice: undefined,
type: 2,
status: 1, //1=정상, 0=실패
root: undefined
}
}
✔ hardhat ethers test (2557ms)
✔ ethers test

2 passing (3s)



2. 그냥 ethers에서 transaction 생성&실행

hardhat과 달리 ethers는 기본정보를 알아서 채워주지 않음

코드 2-1

  it("ethers test", async () => {
    const provider = new ethers.JsonRpcProvider("http://localhost:8545");
    //hardhat network 서버와 상호작용 하는 provider
    const bobWallet = new ethers.Wallet(
      "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
      provider
    );
    // npx hardhat node 터미널에 쳐서 network 실행
    // private key 넣어줌 ==> 잔고 o
    // createRandom ==> 잔고 x
    const aliceWallet = new ethers.Wallet(
      "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
    );
    const tx = {
      from: bobWallet.address,
      to: aliceWallet.address,
      value: ethers.parseEther("100"),
    };
    const populatedTx = await bobWallet.populateTransaction(tx);
    console.log(populatedTx);
    const signedTx = await bobWallet.signTransaction(tx); //코드2-2 변경 (tx부분)
    // const txHash = await provider.send("eth_sendRawTransaction", [signedTx]);
    // console.log(txHash);
  });

==> 필요한 필드를 provider populatedTx 이런 것들로 따로 채워줌!!
(필요한 필드? ==> ex. chainId..)


provider + populatedTx 터미널 결과...

hardhat-test
{
to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
value: 100000000000000000000n,
nonce: 0,
gasLimit: 21001n,
chainId: 31337n,
type: 2,
maxFeePerGas: 3000000000n,
maxPriorityFeePerGas: 1000000000n
}

...
...

필드 채워진 거 확인 후

const signedTx = await

//아래 코드에서 tx --> populatedTx 변경
bobWallet.signTransaction(populatedTx); 


//주석 해제
const txHash = await provider.send("eth_sendRawTransaction", [signedTx]);
console.log(txHash);

위의 코드2-1에서 표시해둔 부분의 tx를 populatedTx로 변경해주고,

console.log(populatedTx); //삭제

변경했던 코드 위에 있던 이 코드는 확인 용도였으니 지워주고,

주석처리 한 부분 살려주면 코드 2-2가 된다

코드2-2

const populatedTx = await bobWallet.populateTransaction(tx);
const signedTx = await bobWallet.signTransaction(signedTx);
const txHash = await provider.send("eth_sendRawTransaction", [signedTx]);
console.log(txHash);

실행해주면

hardhat-test
0xb7f2251f8306d381ce21ae944aed4be99412d7db1dfeed49415ddfa0c505c96a
✔ ethers test (186ms)

1 passing (195ms)

txHash가 정상적으로 출력됨.
..
..
..

코드2-3

console.log(await provider.getBalance(bobWallet));
console.log(await provider.getBalance(aliceWallet));

// ETH단위로 출력 시 ethers.formatEther 사용 (아래 예시)
// console.log(ethers.formatEther(await provider.getBalance(bobWallet)));  

코드2-2에서 console.log(txHash); 대신 위의 코드 2-3을 넣어주고
실행할 시 잔고를 볼 수 있다.

profile
배운 내용 정리&기록, 스크랩

0개의 댓글