Hardhat_02

atesi·2022년 10월 20일
0

blockchain

목록 보기
10/12

sending a "raw" transaction in ethersjs

console.log("Let's deploy with only transaction data!");
const nonce = await wallet.getTransactionCount();
const tx = {
	nonce: nonce,
	gasPrice: 20000000000,
	gasLimit: 100000,
	to: null,
	value: 0,
	data: "0x608060405234801561001...",
	chainId: 5777,
};
//   const signedTxResponse = await wallet.signTransaction(tx);
const sentTxResponse = await wallet.sendTransaction(tx);
await sentTxResponse.wait(1);
console.log(sentTxResponse);

gasPrice는 ganache 상단에서 참조. dataSimpleStrage_sol_SimpleStorage.bin에서 가져온다.
chainId는 ganache의 NETWORKID를 가져온다.
sendTransaction()에는 signTransaction()가 포함되어 있다.

Interacting with Contracts

const currentFavoriteNumber = await contract.retrieve();

계약을 로컬 블록체인에 배포했으므로 interacting이 가능하다. Remix애서 변수 등을 호출할 수 있던 버튼이 있었는데 ether에서도 수행해보자.

const currentFavoriteNumber = await contract.retrieve();

모든 계약 객체는 abi에 묘사 되어있다. SimpleStrage_sol_SimpleStorage.abi를 읽기쉽게 json형식으로 바꾼 뒤 포멧팅 이후 다시 abi로 바꿔준다.
로그를 찍어보면 BigNumber를 반환한다. 이는 ether에서 제공하는 라이브러리로 자바스크립트가 이해할 수 없는 숫자작업에 도움을 준다.

console.log(currentFavoriteNumber.toString()); 

지정하지 않으면 초기화되어 0을 반환한다. store()함수를 이용해서 지정해주자.

const transactionResponse = await contract.store("7");
const transactionReceipt = await transactionResponse.wait(1);

이제 계약에서 함수를 호출하면 transactionResponse를 얻고 transactionResponse가 완료될 때까지 wait하면 transactionReceipt를 얻는다.

const updatedFavoriteNumber = await contract.retrieve();
console.log(`Updated favorite number is ${updatedFavoriteNumber.toString()}`);

새롭게 변수에 지정하고 호출하면 값을 반환받는다.

Environment Variables

.env 파일을 생성

PRIVATE_KEY="46285b7eda88a8cef21e17c842...",
RPC_URL="http://127.0.0.1:7545"

저장

const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL)
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

위와같이 환경변수를 이용해주자.
.gitignore로 관리

encryptKey.js

더 나은 관리를 위해 encryptKey.js생성해준다.

const ethers = require("ethers");
const fs = require("fs-extra");
require("dotenv").config();

async function main() {
  const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
  const encryptedJsonKey = await wallet.encrypt(
    process.env.PRIVATE_KEY_PASSWORD,
    process.env.PRIVATE_KEY
  );
  console.log(encryptedJsonKey);
  fs.writeFileSync("./.encryptedKey.json", encryptedJsonKey);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });
PRIVATE_KEY="46285b7eda88a8cef21e17c842...",
RPC_URL="http://127.0.0.1:7545"
PRIVATE_KEY_PASSWORD=password 

.env파일에 password를 추가해준다.

node encryptKey.js

.encryptedKey.json파일이 생성되는데 password를 이용해서 해독할 수 있는 json key를 생성한다.

//const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const encryptedJson = fs.readFileSync("./.encryptedKey.json", "utf-8");
let wallet = new ethers.Wallet.fromEncryptedJsonSync(
  encryptedJson,
  process.env.PRIVATE_KEY_PASSWORD
);
wallet = await wallet.connect(provider);

.encryptedKey.json 파일을 읽고 이 변수를 fromEncryptedJsonSync 함수에 전달한다. 이 함수는 암호화된 json key와 비밀번호라는 2개의 매개변수를 사용한다. 그 다음 지갑을 공급자에 연결. .env에서 url을 제외한 변수들을 지운 후 실행하면 문제 없이 된다.

Deploying to a testnet or mainnet

alchemy
알케미는 이더리움 블록체인 개발을 위한 API 노드서비스를 제공한다. http엔드포인트를 가져와 RPC URL대신 입력해준다. 메타마스크에서 private key도 가져온다.

 const contractFactory = new ethers.ContractFactory(abi, binary, wallet);
 console.log("Deploying, please wait...");
 const contract = await contractFactory.deploy(); 
 await contract.deployTransaction.wait(1);
 console.log(`Contract Address: ${contract.address}`);

성공적으로 배포되었다.


완성된 코드
const ethers = require("ethers")
const fs = require("fs-extra")
require("dotenv").config()

async function main() {
    const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL)
    const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
    // const encryptedJson = fs.readFileSync("./.encryptedKey.json", "utf8")
    // let wallet = new ethers.Wallet.fromEncryptedJsonSync(
    //     encryptedJson,
    //     process.env.PRIVATE_KEY_PASSWORD
    // )
    // wallet = await wallet.connect(provider)
    const abi = fs.readFileSync(
        "./SimpleStorage_sol_SimpleStorage.abi",
        "utf-8"
    )
    const binary = fs.readFileSync(
        "./SimpleStorage_sol_SimpleStorage.bin",
        "utf-8"
    )
    const contractFactory = new ethers.ContractFactory(abi, binary, wallet)
    console.log("Deploying, please wait...")
    const contract = await contractFactory.deploy()
    await contract.deployTransaction.wait(1)
    console.log(`Contract Address: {contract.address}`)

      console.log("Let's deploy with only transaction data!");
      const nonce = await wallet.getTransactionCount();
      const tx = {
        nonce: nonce,
        gasPrice: 20000000000,
        gasLimit: 100000,
        to: null,
        value: 0,
        data: "0x6080604052348015610...",
        chainId: 5777,
      };
    //   const signedTxResponse = await wallet.signTransaction(tx);
      const sentTxResponse = await wallet.sendTransaction(tx);
      await sentTxResponse.wait(1);
      console.log(sentTxResponse);
    
    const currentFavoriteNumber = await contract.retrieve()
    console.log(`Current Favorite Numvber: ${currentFavoriteNumber.toString()}`)
    const transactionResopense = await contract.store("7")
    const transactionReceipt = await transactionResopense.wait(1)
    const updatedFavoriteNumber = await contract.retrieve()
    console.log(`Updated favorite number is: ${updatedFavoriteNumber}`)
}

main()
    .then(() => ProcessingInstruction.exit(0))
    .catch((error) => {
        console.error(error)
        process.exit(1)
    })




이 시리즈는 freeCodeCamp.org의 강의를 들으면서 공부한 내용을 정리하기 위해 작성했습니다.

profile
Action!

0개의 댓글