728x90
과제내용
" 스마트 컨트랙트를 이용해서 로또 제작해보세요~ " 가 과제 내용이었다.....
힘... 내볼게요....ㅎㅎ
결과물
#. 폴더의 경로는 다음과 같다.
1. src/contracts/lotto.sol_로또 작업을 구현하기 위한 solidity 코드를 작성한다.
Lotto 컨트럭트에서 사용할 변수를 선언한다.
- lottoNums : 로또 숫자를 뽑을 숫자 배열을 담는다. ( 1 ~ 45의 숫자)
- selecNums : lottoNums에서 뽑은 숫자 6개를 배열로 담는다. (중복되지 않아야 한다.)
- numHistory : 로또 추첨 결과(selecNums)를 담는다. (이중 배열)
getSelecLotto 함수는 로또를 추첨한 결과인 selecNums를 반환한다. 'public view' 속성으로 읽기만 할 수 있는 반환값을 가진다. 반환값은 uint256의 배열 형식을 가진다. 이 부분에서 매개변수에 'returns(uint256[] memory)'로 작성을 했는데, memory를 작성하지 않으면 에러가 발생했다... 왜 작성을 해야하는지 아직 이유는 모르겠어서 나중에 찾아보도록 하자 ㅎㅎ 같은 방식으로 getNums 함수를 작성해 추첨할 수 있는 번호들을 반환했다.
setLotto 함수는 로또를 추천하는 역할을 수행한다.
// SPDX-License-Identifier : MIT
pragma solidity ^0.8.13;
contract Lotto{
uint256[] lottoNums;
uint256[] selecNums;
uint256[][] numHistory;
constructor(){
// for (uint256 i = 1; i < 46; i++) {
// lottoNums.push(i);
// }
}
function getSelecLotto() public view returns(uint256[] memory){
return selecNums;
}
function getNums() public view returns(uint256[] memory){
return lottoNums;
}
function setLotto()public returns(uint256[] memory){
delete lottoNums;
delete selecNums;
for (uint256 i = 1; i < 46; i++) {
lottoNums.push(i);
}
for (uint256 i = 0; i < 6 ; i++) {
uint256 selec = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, i))) % lottoNums.length;
selecNums.push(lottoNums[selec]);
lottoNums[selec] = lottoNums[lottoNums.length -1];
lottoNums.pop();
}
numHistory.push(selecNums);
return selecNums;
}
function getHistory() public view returns(uint256[][] memory){
return numHistory;
}
}
import "./App.css";
import { useEffect, useState } from "react";
import Web3 from "web3";
function App() {
const abi = [
{ inputs: [], stateMutability: "nonpayable", type: "constructor" },
{
inputs: [],
name: "getHistory",
outputs: [{ internalType: "uint256[][]", name: "", type: "uint256[][]" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "getNums",
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "getSelecLotto",
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "setLotto",
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
stateMutability: "nonpayable",
type: "function",
},
];
const [account, setAccount] = useState(null);
const [balance, setBalance] = useState(0);
const [web3, setWeb3] = useState(null);
const [res, setRes] = useState("");
const [lottoNums, setLottoNums] = useState([]);
const [lotto, setLotto] = useState([]);
useEffect(() => {
(async () => {
const [data] = await window.ethereum.request({
method: "eth_requestAccounts",
});
setWeb3(new Web3(window.ethereum));
setAccount(data);
})();
}, []);
const getHistory = async () => {
const getNumsHash = await web3.eth.abi.encodeFunctionCall(abi[1], []);
const nums = await web3.eth.call({
to: res,
data: getNumsHash,
});
const hexString = nums;
const decodedData = web3.eth.abi.decodeParameters(
["uint256[][]"],
hexString
);
const historyNums = decodedData[0].map((subArr) =>
subArr.map((el) => Number(el))
);
let temp="";
temp += "<div>"
historyNums.forEach((el) => {
let arr = "";
el.forEach((e)=>{
arr += `<span>${e}, </span>`
});
temp += "</br>";
temp += arr;
});
temp += "</div>"
document.querySelector("#history").innerHTML = temp;
};
// 전체 번호를 가져옴
const getnums = async () => {
const view = document.getElementById("view");
const getNumsHash = await web3.eth.abi.encodeFunctionCall(abi[2], []);
const nums = await web3.eth.call({
to: res,
data: getNumsHash,
});
const hexString = nums;
let arr = hexString.slice(2).match(/.{1,64}/g);
arr.shift();
let length = parseInt(arr.shift(), 16);
arr = arr.slice(0, length).map((hex) => parseInt(hex, 16));
view.innerHTML = arr;
setLottoNums(arr);
};
const balanceBtn = async () => {
const bal = await web3.eth.getBalance(account);
const balance = await web3.utils.fromWei(bal, "ether");
setBalance(balance);
};
const TransactionBtn = async () => {
const bintext = document.getElementById("bintext");
web3.eth
.sendTransaction({
from: account,
gas: "3000000",
data: bintext.value,
})
.then((e) => {
setRes(e.contractAddress);
// console.log(e.contractAddress);
});
};
const selecLotto = async () => {
const setLottoNums = await web3.eth.abi.encodeFunctionCall(abi[4], []);
const tx = {
from: account,
to: res,
data: setLottoNums,
gas: 1500000,
gasPrice: 200000000,
};
const data = await web3.eth.sendTransaction(tx);
getSelecNums();
getHistory();
};
const getSelecNums = async () => {
const selecview = document.getElementById("selecview");
const getNumsHash = await web3.eth.abi.encodeFunctionCall(abi[3], []);
const nums = await web3.eth.call({
to: res,
data: getNumsHash,
});
const hexString = nums;
let arr = hexString.slice(2).match(/.{1,64}/g);
arr.shift();
let length = parseInt(arr.shift(), 16);
arr = arr.slice(0, length).map((hex) => parseInt(hex, 16));
selecview.innerHTML = arr;
setLotto(arr);
};
return (
<div className="App">
<div>
<div>{account}</div>
<div>{balance} ETH</div>
<button onClick={balanceBtn}>잔액조회</button>
</div>
<div id="view"></div>
<button onClick={getnums}>로또 전체 번호</button>
<div id="selecview"></div>
<button onClick={selecLotto}>로또 추첨</button>
<div>
<input type="text" placeholder="bin코드" id="bintext"></input>
<button onClick={TransactionBtn}>트랜잭션 배포</button>
</div>
<div id="history"></div>
</div>
);
}
export default App;
728x90
'블록체인_9기 > 과제' 카테고리의 다른 글
51강_220718_React(useContext, useMemo 활용_TODOLIST 제작) (1) | 2023.07.19 |
---|---|
49강_220710_React(Redux 활용_간단한 주문페이지 제작) (0) | 2023.07.10 |
48강_220706_React(TODO LIST 제작) (0) | 2023.07.07 |
47강_220705_React(지뢰찾기 제작) (1) | 2023.07.05 |
46강_220704_React(캘린더 제작) (0) | 2023.07.04 |