Описание изменений
This commit is contained in:
@@ -1,27 +1,18 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
contract MyContract {
|
||||
address public owner;
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
||||
|
||||
contract MyContract is Ownable, ReentrancyGuard {
|
||||
uint256 public price;
|
||||
|
||||
event Purchase(address buyer, uint256 amount);
|
||||
|
||||
constructor() {
|
||||
owner = msg.sender;
|
||||
price = 0.01 ether; // Начальная цена 0.01 ETH
|
||||
}
|
||||
|
||||
modifier onlyOwner() {
|
||||
require(msg.sender == owner, "Only owner can call this function");
|
||||
_;
|
||||
}
|
||||
|
||||
function setOwner(address newOwner) public onlyOwner {
|
||||
require(newOwner != address(0), "New owner cannot be zero address");
|
||||
owner = newOwner;
|
||||
}
|
||||
|
||||
function setPrice(uint256 newPrice) public onlyOwner {
|
||||
price = newPrice;
|
||||
}
|
||||
@@ -30,12 +21,13 @@ contract MyContract {
|
||||
return price;
|
||||
}
|
||||
|
||||
function purchase(uint256 amount) public payable {
|
||||
function purchase(uint256 amount) public payable nonReentrant {
|
||||
require(msg.value == price * amount, "Incorrect payment amount");
|
||||
emit Purchase(msg.sender, amount);
|
||||
}
|
||||
|
||||
function withdraw() public onlyOwner {
|
||||
payable(owner).transfer(address(this).balance);
|
||||
function withdraw() public onlyOwner nonReentrant {
|
||||
(bool success, ) = owner().call{value: address(this).balance}("");
|
||||
require(success, "Transfer failed");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
require("@nomiclabs/hardhat-waffle");
|
||||
require("dotenv").config();
|
||||
|
||||
module.exports = {
|
||||
solidity: "0.8.0",
|
||||
networks: {
|
||||
sepolia: {
|
||||
url: process.env.ETHEREUM_NETWORK_URL,
|
||||
accounts: [process.env.PRIVATE_KEY]
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
require('dotenv').config()
|
||||
require('@nomicfoundation/hardhat-ethers')
|
||||
require('@nomicfoundation/hardhat-chai-matchers')
|
||||
require("dotenv").config();
|
||||
require("@nomicfoundation/hardhat-ethers");
|
||||
require("@nomicfoundation/hardhat-chai-matchers");
|
||||
|
||||
module.exports = {
|
||||
solidity: "0.8.0",
|
||||
solidity: "0.8.19",
|
||||
networks: {
|
||||
sepolia: {
|
||||
url: process.env.SEPOLIA_URL,
|
||||
url: process.env.ETHEREUM_NETWORK_URL,
|
||||
accounts: [process.env.PRIVATE_KEY]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"compile": "hardhat compile",
|
||||
"deploy": "hardhat run scripts/deploy.js --network sepolia",
|
||||
@@ -14,14 +13,14 @@
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.3",
|
||||
"express-session": "^1.18.0",
|
||||
"hardhat": "^2.20.1",
|
||||
"siwe": "^3.0.0",
|
||||
"nodemon": "^3.1.0"
|
||||
"nodemon": "^3.1.0",
|
||||
"siwe": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"hardhat": "^2.21.0",
|
||||
"@nomicfoundation/hardhat-ethers": "^3.0.5",
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
|
||||
"@types/sinon-chai": "^3.2.3",
|
||||
"@openzeppelin/contracts": "4.9.3",
|
||||
"chai": "4.3.7",
|
||||
"dotenv": "^16.4.7",
|
||||
"ethers": "^6.11.1"
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log("Начинаем деплой контракта...");
|
||||
|
||||
console.log('Deploying contracts with the account:', deployer.address);
|
||||
// Получаем контракт
|
||||
const MyContract = await hre.ethers.getContractFactory("MyContract");
|
||||
|
||||
const MyContract = await ethers.getContractFactory('MyContract');
|
||||
const contract = await MyContract.deploy();
|
||||
// Деплоим контракт
|
||||
const myContract = await MyContract.deploy();
|
||||
await myContract.waitForDeployment();
|
||||
|
||||
console.log('Contract deployed to:', contract.address);
|
||||
const address = await myContract.getAddress();
|
||||
console.log("Контракт развернут по адресу:", address);
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import session from 'express-session';
|
||||
import { SiweMessage, generateNonce } from 'siwe';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname } from 'path';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const session = require('express-session');
|
||||
const { SiweMessage, generateNonce } = require('siwe');
|
||||
const path = require('path');
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -69,57 +65,37 @@ app.post('/verify', async (req, res) => {
|
||||
throw new Error('Invalid session');
|
||||
}
|
||||
|
||||
if (!signature || !message) {
|
||||
console.error('Отсутствует подпись или сообщение');
|
||||
throw new Error('Invalid signature or message');
|
||||
let siweMessage;
|
||||
try {
|
||||
siweMessage = new SiweMessage(message);
|
||||
const fields = await siweMessage.validate(signature);
|
||||
|
||||
if (fields.nonce !== req.session.nonce) {
|
||||
console.error('Nonce не совпадает');
|
||||
throw new Error('Invalid nonce');
|
||||
}
|
||||
|
||||
// Создаем и верифицируем SIWE сообщение
|
||||
console.log('Начинаем парсинг SIWE сообщения...');
|
||||
const siweMessage = new SiweMessage(message);
|
||||
|
||||
console.log('Парсинг успешен:', {
|
||||
domain: siweMessage.domain,
|
||||
address: siweMessage.address,
|
||||
nonce: siweMessage.nonce
|
||||
});
|
||||
|
||||
const { success, data: fields } = await siweMessage.verify({
|
||||
signature,
|
||||
domain: siweMessage.domain,
|
||||
nonce: req.session.nonce
|
||||
});
|
||||
|
||||
console.log('Результат верификации:', { success, fields });
|
||||
|
||||
if (!success) {
|
||||
throw new Error('Signature verification failed');
|
||||
}
|
||||
|
||||
// Сохраняем сессию
|
||||
req.session.authenticated = true;
|
||||
console.log('Сообщение успешно верифицировано');
|
||||
req.session.siwe = fields;
|
||||
req.session.authenticated = true;
|
||||
req.session.nonce = null;
|
||||
|
||||
console.log('Сессия сохранена:', {
|
||||
authenticated: true,
|
||||
address: fields.address
|
||||
});
|
||||
|
||||
req.session.save(() => {
|
||||
console.log('Session saved successfully');
|
||||
res.status(200).json({
|
||||
res.json({
|
||||
success: true,
|
||||
address: fields.address
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Ошибка валидации сообщения:', error);
|
||||
req.session.authenticated = false;
|
||||
req.session.siwe = null;
|
||||
req.session.nonce = null;
|
||||
throw error;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка верификации:', error);
|
||||
req.session.authenticated = false;
|
||||
req.session.nonce = null;
|
||||
req.session.siwe = null;
|
||||
res.status(400).json({
|
||||
error: 'Verification failed',
|
||||
message: error.message
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -184,7 +160,7 @@ app.use((err, req, res, next) => {
|
||||
});
|
||||
});
|
||||
|
||||
const PORT = 3000;
|
||||
const PORT = process.env.PORT || 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`SIWE сервер запущен на порту ${PORT}`);
|
||||
console.log('Доступные эндпоинты:');
|
||||
|
||||
@@ -371,6 +371,11 @@
|
||||
"@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.2"
|
||||
"@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.2"
|
||||
|
||||
"@openzeppelin/contracts@4.9.3":
|
||||
version "4.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364"
|
||||
integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==
|
||||
|
||||
"@scure/base@~1.1.0":
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1"
|
||||
@@ -560,26 +565,6 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/sinon-chai@^3.2.3":
|
||||
version "3.2.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.12.tgz#c7cb06bee44a534ec84f3a5534c3a3a46fd779b6"
|
||||
integrity sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==
|
||||
dependencies:
|
||||
"@types/chai" "*"
|
||||
"@types/sinon" "*"
|
||||
|
||||
"@types/sinon@*":
|
||||
version "17.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-17.0.3.tgz#9aa7e62f0a323b9ead177ed23a36ea757141a5fa"
|
||||
integrity sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==
|
||||
dependencies:
|
||||
"@types/sinonjs__fake-timers" "*"
|
||||
|
||||
"@types/sinonjs__fake-timers@*":
|
||||
version "8.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz#5fd3592ff10c1e9695d377020c033116cc2889f2"
|
||||
integrity sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==
|
||||
|
||||
accepts@~1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||
@@ -1448,7 +1433,7 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
|
||||
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
|
||||
|
||||
hardhat@^2.20.1:
|
||||
hardhat@^2.21.0:
|
||||
version "2.22.18"
|
||||
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.18.tgz#e299a26a67b521bbb225370eb47a032d4e097e3a"
|
||||
integrity sha512-2+kUz39gvMo56s75cfLBhiFedkQf+gXdrwCcz4R/5wW0oBdwiyfj2q9BIkMoaA0WIGYYMU2I1Cc4ucTunhfjzw==
|
||||
|
||||
@@ -105,7 +105,7 @@ const isAuthenticated = ref(false)
|
||||
// Константы
|
||||
const SEPOLIA_CHAIN_ID = 11155111
|
||||
const provider = new JsonRpcProvider(import.meta.env.VITE_APP_ETHEREUM_NETWORK_URL)
|
||||
const contractAddress = '0xD1789d2E00e4af3157330ADFbb813427696c8A01'
|
||||
const contractAddress = '0xFF7602583E82C097Ae548Fc8B894F0a73089985E'
|
||||
const contractABI = [
|
||||
'function purchase(uint256 amount) payable',
|
||||
'function price() view returns (uint256)',
|
||||
|
||||
Reference in New Issue
Block a user