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 상단에서 참조. data
는 SimpleStrage_sol_SimpleStorage.bin
에서 가져온다.
chainId
는 ganache의 NETWORKID
를 가져온다.
sendTransaction()에는 signTransaction()가 포함되어 있다.
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()}`);
새롭게 변수에 지정하고 호출하면 값을 반환받는다.
.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생성해준다.
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을 제외한 변수들을 지운 후 실행하면 문제 없이 된다.
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의 강의를 들으면서 공부한 내용을 정리하기 위해 작성했습니다.