우리는 컨트랙트 작성을 끝냈으면 이를 플랫폼에서 사용할수 있게끔 만들어줘야한다.
보통 프론트에서 메타마스크를 통해 트랜잭션을 날리는 방법을 쓰지만 유저들에게 접근성이 좋아야하기 때문에
이해하기 힘든 지갑 부분을 제외하는 방법, 백엔드에서 처리를 하는 방식을 주로 택한다. 이에 따른 문제점은 확실히 존재하지만
현재로써 지갑을 이해하지못하는 유저들이 사용하기에 가장 좋은 방법 인것 같다.
1. 이더리움 통신 연결
////이더리움 테스트넷 goeril 사용////
const Web3= require('web3');
const web3 = new Web3(
new Web3.providers.HttpProvider("https://ethereum-goerli-rpc.allthatnode.com")
);
2. 컨트랙트 abi, bytecode 추출
작성한 컨트렉트를 배포 하기 이전에 컴파일링을 통해 abi, bytecode를 뽑아내야한다.
이를 truffle을 통해 진행하였으며 이에 대한 내용은 따로 다루도록 하겠다. 배포까지 가능하다 truffle에서
const jsonRead = fs.readFileSync("your Smart Contract Json File path", "utf-8");
//파일을 읽고 처리를 해줘야 하기 때문에 readFileSync를 사용한다.
const JsonToAbi = jsonRead.abi;
const JsonToByte = jsonRead.bytecode;
//jsonRead를 까보게 되면 abi 와 bytecode가 분리되어 있다 하여 위의 함수식으로 구분가능하다.
3. 컨트랙트 배포
const deploy =async() => {
const nftContract = new web3.eth.Contract(jsonToAbi);
// 객체 생성 : 이더리움 블록체인에서 스마트 계약과 쉽게 상호 작용할 수 있도록 한다
const deployContractData = nftContract.deploy({
data : jsonToByte,
arguments: [
...
]
}).encodeABI;
/// transaction의 data 부분에 넣어줄 함수
//영수증 만들기//
const deployTx = {
from: "MyAddress",
data: deployContractData,
nonce: nonce: web3.eth.getTransactionCount(MyAddress),
gasLimit: web3.utils.toHex(10000000),
gasPrice: web3.utils.toHex(web3.utils.toWei("10", "gwei"))
};
//가스비 자동 추정 계산은 밑에서 다루겠다.
///서명하기///
const deployCreateTransaction = await web3.eth.signTransaction(
deployTx,
yourAccountPrivateKey
);
///트랜잭션 보내기///
const sendDeployTransaction = await web3.eth.sendSignedTransaction(
deployCreateTransaction.rawTransaction
);
console.log("Contract Address", sendDeployTransaction.contractAddress)
//생성된 컨트렉트 주소//
}
4. 가스비 계산
이더리움 네트워크 환경에 따라 트랜잭션을 바로 바로 보낼수 있는 가스비가 계속해서 변동한다.
하여 계산하기 편하게 만들 필요가 있다.
const gasprice = await web3.eth.getGasPrice();
const gasPrice = Math.round(Number(gasprice) + Number(gasprice / 10));
//이더리움 네트워크에 현재 가스비를 받아온다
5. 컨트랙트 함수 호출
이전에 컨트랙트 배포를 통해 우리는 컨트랙트 주소를 뽑아냈다. 컨트랙트 함수 호출을 편히 하기 위해
다시 객체화를 한다.
const newContract = (web3, abi, ca) => {
return new web3.eth.Contract(abi, ca, {
from: contractAddress,
gas: 3000000,
});
};
const nftContract = newContract(web3, JsonToAbi, contractAddress);
이제 컨트랙트 내의 어떠한 함수를 백단에서 사용해보려고 한다.
순서는 다음과 같다.
- 사용하려는 컨트랙트 내의 함수 호출
- 영수증 생성
- 영수증 sign
- sign 완료된 영수증 전송
예제로 들어보자 위의 가스 추정까지 합쳐서 구현해보겠다.
const any = async () => {
//가스비 계산
const gasprice = await web3.eth.getGasPrice();
const gasPrice = Math.round(Number(gasprice) + Number(gasprice / 10));
//컨트랙트 함수 호출, 함수 파라미터 입력
const anyThingData = await nftContract.methods.myMethodName(parameter).encodeABI();
//영수증 생성
const tx = {
data: anyThingData,
from: myAddreess,
to: contractAddress,
nonce: web3.eth.getTransactionCount(myAddreess, "latest"),
gasPrice: gasPrice,
gasLimit: 5000000
};
//영수증 서명
const signAnyThingTx = await web3.eth.accounts.signTransaction(
tx, myAddress
);
//서명된 영수증 전송
const sendSignedAnyThingTx = await web3.eth.sendSignedTransaction(
signAnyThingTx.rawTransaction
//rawTransaciont은 어떻게 만들어질까
//이에 대한 내용은 다른 페이지에서 작성하겠다.
);
console.log("sendSignedAnyThingTx", sendSignedAnyThingTx);
}
6. 마무리
web3를 이용해 블록체인 통신 연결 부터 컨트랙트 배포, 함수 호출까지 알아보았다.
이와 같은 방법은 유저들이 지갑을 설치하지 않고 서버의 백단에서 모든 부분을 다 처리 해주는 방법이기 때문에
유저들의 편의성을 증가 시켜줄 수 있지만 서버가 유저의 프라이빗 키를 관리해주기 때문에 이 부분에서 상당히 보안에 힘을 써야한다.
사실상 이와 같은 방법은 블록체인의 이념과 상충하는 부분이라 생각하지만
이전 글에서도 계속 말했다시피 아직 블록체인을 제대로 이해 하지 못한 유저들은 지갑의 사용 부분에서 높은 허들을 가져가기 때문에
유저 친화도를 위해 일부를 감수해야하는 부분이다.
블록체인이 좀 더 보편화가 되고 지갑이 보편화가 된다면 이러한 과정은 필요 없을 것이다.
댓글