Web3 스토어
Source: Dev.to
Overview
Solidity와 ethers.js를 사용해 학습용 데모 Web3 스토어를 작성하고 배포했습니다. 이전 책에서 권장하던 도구들(web3.js, Truffle, Ganache)은 이제 구식이므로 최신 툴링으로 프로젝트를 구축했습니다.
Setup
Choosing a Development Framework
스마트 계약을 빌드하고 배포하기 위해 Forge(Foundry의 일부)를 Hardhat보다 선택했습니다. 두 툴 모두 로컬 테스트넷을 제공하는데, 저는 Anvil—Forge의 빠른 인‑메모리 Ethereum 노드—를 사용했습니다.
콘솔에서 Anvil을 시작하면 자동으로 자금이 충전된 계정이 생성되고, MetaMask가 연결할 수 있는 RPC 엔드포인트(예: http://127.0.0.1:8545)가 출력됩니다.
Smart Contract
이 계약은 두 가지 함수를 구현합니다:
Purchase an Item
function purchaseItem(uint8 _itemId) external payable {
uint256 itemCost = 2 gwei; // 0.0012 USD / 0.18 RUB;
// Forward the funds to the seller
(bool success, ) = STORE_ADDRESS.call{value: itemCost}("");
require(success, "Transfer failed");
boughtItems[msg.sender].push(_itemId);
}
View Purchased Items
function getBoughtItems() external view returns (uint8[] memory) {
return boughtItems[msg.sender];
}
Deploying the Contract
테스트와 컴파일을 마친 뒤, Forge를 사용해 계약을 배포합니다:
forge create ./src/Store.sol:Store \
--private-key \
--rpc-url \
--broadcast \
--constructor-args
명령이 실행되면 배포된 계약 주소가 반환됩니다.
Frontend Integration
스토어 애플리케이션은 ethers v6를 이용해 MetaMask와 블록체인에 연결합니다.
Initialize Provider and Signer
import { ethers } from "ethers";
const provider = new ethers.BrowserProvider(window.ethereum);
const signerObj = await provider.getSigner();
const balance = await provider.getBalance(signerObj.address);
const balanceFormatted = ethers.formatEther(balance);
Load Contract ABI
import ContractArtifact from "***/Store.json";
const abi = ContractArtifact.abi;
Create Contract Instance
const contract = new ethers.Contract(CONTRACT_ADDRESS, abi, signerObj);
Call Contract Functions
Purchase an Item
contract.purchaseItem(itemId, {
value: ethers.parseUnits("2", "gwei") // attach the wei
}).then((tx) => tx.wait())
.then(() => {
const newItems = items.add(itemId);
setItems(newItems);
});
Retrieve Purchased Items
const userItems = await contract.getBoughtItems();
Deployment to Live Network
개발이 완료되면 동일한 Forge 워크플로우를 사용해 스토어와 계약을 실제 네트워크에 배포할 수 있습니다. 이때 RPC URL과 개인 키를 적절히 업데이트하면 됩니다.
읽어 주셔서 감사합니다! 피드백이나 제안이 있으면 언제든 알려 주세요.
Project link: