├── .prettierrc ├── .solhintignore ├── .npmignore ├── .eslintignore ├── .prettierignore ├── .gitignore ├── .solhint.json ├── .env.example ├── contracts └── problems │ ├── plus │ ├── MyPlusCalculator.sol │ └── PlusCalculatorProblem.sol │ ├── minus │ ├── MyMinusCalculator.sol │ └── MinusCalculatorProblem.sol │ ├── division │ ├── MyDivisionCalculator.sol │ └── DivisionCalculatorProblem.sol │ └── multiplication │ ├── MyMultiplicationCalculator.sol │ └── MultiplicationCalculatorProblem.sol ├── .eslintrc.js ├── scripts └── plusCalculatorSol.js ├── package.json ├── hardhat.config.js └── README.md /.prettierrc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | hardhat.config.js 2 | scripts 3 | test 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | coverage* 5 | gasReporterOutput.json 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | 7 | #Hardhat files 8 | cache 9 | artifacts 10 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "compiler-version": ["error", "^0.8.0"], 5 | "func-visibility": ["warn", { "ignoreConstructors": true }] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 2 | ROPSTEN_URL=https://eth-ropsten.alchemyapi.io/v2/ 3 | RINKEBY_URL=https://rinkeby.infura.io/v3/ 4 | PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1 5 | -------------------------------------------------------------------------------- /contracts/problems/plus/MyPlusCalculator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "./PlusCalculatorProblem.sol"; 5 | 6 | contract MyPlusCalculator is IPlusCalculator { 7 | function plus(uint256 input1, uint256 input2) override public pure returns (uint256){ 8 | return input1 + input2; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /contracts/problems/minus/MyMinusCalculator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface IMinusCalculator { 5 | function minus(uint256, uint256) external pure returns (uint256); 6 | } 7 | 8 | contract MyMinusCalculator is IMinusCalculator { 9 | function minus(uint256 input1, uint256 input2) override public pure returns (uint256){ 10 | // TODO 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/problems/division/MyDivisionCalculator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface IDivisionCalculator { 5 | function divide(uint256, uint256) external pure returns (uint256); 6 | } 7 | 8 | contract MyDivisionCalculator is IDivisionCalculator { 9 | function divide(uint256 input1, uint256 input2) override public pure returns (uint256){ 10 | // TODO 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es2021: true, 5 | mocha: true, 6 | node: true, 7 | }, 8 | extends: [ 9 | "standard", 10 | "plugin:prettier/recommended", 11 | "plugin:node/recommended", 12 | ], 13 | parserOptions: { 14 | ecmaVersion: 12, 15 | }, 16 | overrides: [ 17 | { 18 | files: ["hardhat.config.js"], 19 | globals: { task: true }, 20 | }, 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /contracts/problems/multiplication/MyMultiplicationCalculator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface IMultiplicationCalculator { 5 | function multiply(uint256, uint256) external pure returns (uint256); 6 | } 7 | 8 | contract MyMultiplicationCalculator is IMultiplicationCalculator { 9 | function multiply(uint256 input1, uint256 input2) override public pure returns (uint256){ 10 | // 여기에 작성하시오. 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/problems/plus/PlusCalculatorProblem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface IPlusCalculator { 5 | function plus(uint256, uint256) external pure returns (uint256); 6 | } 7 | 8 | contract PlusCalculatorProblem{ 9 | IPlusCalculator public plusCalculator; 10 | 11 | function setPlusCalculator(address _plusCalculator) public { 12 | plusCalculator = IPlusCalculator(_plusCalculator); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /contracts/problems/minus/MinusCalculatorProblem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | 6 | interface IMinusCalculator { 7 | function minus(uint256, uint256) external pure returns (uint256); 8 | } 9 | 10 | contract MinusCalculatorProblem{ 11 | IMinusCalculator public minusCalculator; 12 | 13 | function setMinusCalculator(address _minusCalculator) public { 14 | minusCalculator = IMinusCalculator(_minusCalculator); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/problems/division/DivisionCalculatorProblem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | 6 | interface IDivisionCalculator { 7 | function divide(uint256, uint256) external pure returns (uint256); 8 | } 9 | 10 | contract DivisionCalculatorProblem{ 11 | IDivisionCalculator public divisionCalculator; 12 | 13 | function setDivisionCalculator(address _divisionCalculator) public { 14 | divisionCalculator = IDivisionCalculator(_divisionCalculator); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/problems/multiplication/MultiplicationCalculatorProblem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | 6 | interface IMultiplicationCalculator { 7 | function multiply(uint256, uint256) external pure returns (uint256); 8 | } 9 | 10 | contract MultiplicationCalculatorProblem{ 11 | IMultiplicationCalculator public multiplicationCalculator; 12 | 13 | function setMultiplicationCalculator(address _multiplicationCalculator) public { 14 | multiplicationCalculator = IMultiplicationCalculator(_multiplicationCalculator); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/plusCalculatorSol.js: -------------------------------------------------------------------------------- 1 | const { ethers } = require("hardhat"); 2 | const hre = require("hardhat"); 3 | 4 | async function calculatorSol() { 5 | const [myAccount] = await ethers.getSigners(); 6 | 7 | const MyPlusCalculator = await ethers.getContractFactory("MyPlusCalculator"); 8 | const myPlusCalculator = await MyPlusCalculator.connect(myAccount).deploy(); 9 | await myPlusCalculator.deployed(); 10 | 11 | const instance = "0x000...000"; // 이곳에 덧셈 문제 인스턴스 컨트랙트 주소를 넣으세요 12 | const PlusCalculatorProblem = await ethers.getContractFactory("PlusCalculatorProblem"); 13 | const plusCalculatorProblem = PlusCalculatorProblem.attach(instance); 14 | plusCalculatorProblem.connect(myAccount).setPlusCalculator(myPlusCalculator.address); 15 | } 16 | 17 | async function main() { 18 | calculatorSol(); 19 | } 20 | 21 | main().catch((error) => { 22 | console.error(error); 23 | process.exitCode = 1; 24 | }); 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomiclabs/hardhat-ethers": "^2.0.5", 5 | "@nomiclabs/hardhat-etherscan": "^3.0.3", 6 | "@nomiclabs/hardhat-waffle": "^2.0.3", 7 | "chai": "^4.3.6", 8 | "dotenv": "^10.0.0", 9 | "eslint": "^7.32.0", 10 | "eslint-config-prettier": "^8.5.0", 11 | "eslint-config-standard": "^16.0.3", 12 | "eslint-plugin-import": "^2.26.0", 13 | "eslint-plugin-node": "^11.1.0", 14 | "eslint-plugin-prettier": "^3.4.1", 15 | "eslint-plugin-promise": "^5.2.0", 16 | "ethereum-waffle": "^3.4.4", 17 | "ethers": "^5.6.4", 18 | "hardhat": "^2.9.3", 19 | "hardhat-gas-reporter": "^1.0.8", 20 | "prettier": "^2.6.2", 21 | "prettier-plugin-solidity": "^1.0.0-beta.19", 22 | "solhint": "^3.3.7", 23 | "solidity-coverage": "^0.7.21" 24 | }, 25 | "dependencies": { 26 | "@openzeppelin/contracts": "^4.6.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | require("@nomiclabs/hardhat-etherscan"); 4 | require("@nomiclabs/hardhat-waffle"); 5 | require("hardhat-gas-reporter"); 6 | require("solidity-coverage"); 7 | 8 | // This is a sample Hardhat task. To learn how to create your own go to 9 | // https://hardhat.org/guides/create-task.html 10 | task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { 11 | const accounts = await hre.ethers.getSigners(); 12 | 13 | for (const account of accounts) { 14 | console.log(account.address); 15 | } 16 | }); 17 | 18 | // You need to export an object to set up your config 19 | // Go to https://hardhat.org/config/ to learn more 20 | 21 | /** 22 | * @type import('hardhat/config').HardhatUserConfig 23 | */ 24 | module.exports = { 25 | solidity: "0.8.4", 26 | networks: { 27 | ropsten: { 28 | url: process.env.ROPSTEN_URL || "", 29 | accounts: 30 | process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], 31 | }, 32 | // rinkeby 33 | rinkeby: { 34 | url: process.env.RINKEBY_URL || "https://rinkeby.infura.io/v3/", 35 | accounts: 36 | process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], 37 | }, 38 | }, 39 | gasReporter: { 40 | enabled: process.env.REPORT_GAS !== undefined, 41 | currency: "USD", 42 | }, 43 | etherscan: { 44 | apiKey: process.env.ETHERSCAN_API_KEY, 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # web3oj-sol 2 | 3 | ![recommend-node-version](https://img.shields.io/badge/recommend--node--version-16.x-brightgreen) 4 | 5 | 이 프로젝트는 [web3oj](https://app.web3oj.com/)의 문제를 풀수 있는 [hardhat](https://hardhat.org/)기반 개발환경을 제공합니다. 6 | 7 | ## 설정 8 | 9 | ### node version 10 | - [hardhat](https://hardhat.org/tutorial/setting-up-the-environment.html)에서 노드 버전은 >= 12.0 을 지원하지만, 16 버전을 추천드립니다. 11 | 12 | 13 | ### 패키지 설치 14 | ```shell 15 | $ npm install 16 | ``` 17 | 18 | ### `hardhat.config.js` 에 `rinkeby` 네트워크와 Account 설정 19 | 20 | ```js 21 | // hardhat.config.js 22 | ... 23 | module.exports = { 24 | solidity: "0.8.4", 25 | networks: { 26 | // rinkeby 27 | rinkeby: { 28 | url: process.env.RINKEBY_URL || "https://rinkeby.infura.io/v3/...", 29 | accounts: 30 | process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], 31 | }, 32 | }, 33 | gasReporter: { 34 | enabled: process.env.REPORT_GAS !== undefined, 35 | currency: "USD", 36 | }, 37 | etherscan: { 38 | apiKey: process.env.ETHERSCAN_API_KEY, 39 | }, 40 | }; 41 | ``` 42 | 43 | - [INFURA](https://infura.io/)에 회원가입하고 프로젝트를 생성하여 Rinkeby API KEY를 받으세요 44 | - 루트에 .env 파일을 생성하여 아래와 같이 넣으면 RINKEBY_URL, PRIVATE_KEY 를 설정할수 있습니다 45 | 46 | ``` 47 | RINKEBY_URL=https://rinkeby.infura.io/v3/ 48 | PRIVATE_KEY= 49 | ``` 50 | 51 | ### IDE 설정 52 | 53 | #### VSCode 54 | 55 | - [solidity](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) 56 | - `.sol` 파일을 위한 extension 57 | 58 | #### IntelliJ 59 | 60 | - [Solidity](https://plugins.jetbrains.com/plugin/9475-solidity) 61 | - `.sol` 파일을 위한 extension 62 | 63 | ## 예제 덧셈 문제풀기 64 | 65 | 1. 문제 > 덧셈 > 문제풀기 클릭하세요. 66 | 67 | 2. 문제 영역을 복사하여 contracts/PlusCalculatorProblem.sol 로 저장, Sample 영역을 복사하여 contracts/MyPlusCalculator.sol 로 저장하세요. 68 | 69 | 3. MyPlusCalculator.sol에 plus함수를 완성 시킨뒤 실행시켜주세요. 70 | 71 | 4. scripts/plusCalculatorSol.js 를 생성 및 실행하세요. 72 | 73 | 생성 74 | 75 | ```js 76 | // scripts/plusCalculatorSol.js 77 | const { ethers } = require("hardhat"); 78 | const hre = require("hardhat"); 79 | 80 | async function calculatorSol() { 81 | const [myAccount] = await ethers.getSigners(); 82 | 83 | const MyPlusCalculator = await ethers.getContractFactory( 84 | "MyPlusCalculator" 85 | ); 86 | const myPlusCalculator = await MyPlusCalculator.connect( 87 | myAccount 88 | ).deploy(); 89 | await myPlusCalculator.deployed(); 90 | 91 | const instance = "0x000...000"; // 이곳에 덧셈 문제 인스턴스 컨트랙트 주소를 넣으세요 92 | const PlusCalculatorProblem = await ethers.getContractFactory( 93 | "PlusCalculatorProblem" 94 | ); 95 | const plusCalculatorProblem = PlusCalculatorProblem.attach(instance); 96 | plusCalculatorProblem 97 | .connect(myAccount) 98 | .setPlusCalculator(myPlusCalculator.address); 99 | } 100 | 101 | async function main() { 102 | calculatorSol(); 103 | } 104 | 105 | main().catch((error) => { 106 | console.error(error); 107 | process.exitCode = 1; 108 | }); 109 | ``` 110 | 111 | 실행 112 | 113 | ``` 114 | $ npx hardhat --network rinkeby run scripts/plusCalculatorSol.js 115 | ``` 116 | 117 | 5. 제출하기 클릭으로 문제풀이를 마무리하세요. 118 | --------------------------------------------------------------------------------