智能合约安全指南 [特殊字符]️
智能合约安全指南 🛡️

1. 安全基础
1.1 常见漏洞类型
- 重入攻击
- 整数溢出
- 权限控制缺陷
- 随机数漏洞
- 前后运行攻击
- 签名重放
1.2 安全开发原则
- 最小权限原则
- 检查-生效-交互模式
- 状态机安全
- 失败保护机制
2. 重入攻击防护
2.1 基本防护模式
contract ReentrancyGuarded {bool private locked;modifier noReentrant() {require(!locked, "Reentrant call");locked = true;_;locked = false;}function withdraw() external noReentrant {uint256 amount = balances[msg.sender];require(amount > 0, "No balance");balances[msg.sender] = 0; // 先更新状态(bool success, ) = msg.sender.call{value: amount}("");require(success, "Transfer failed");}
}
2.2 检查-生效-交互模式
contract CEIPattern {mapping(address => uint256) private balances;function deposit() external payable {balances[msg.sender] += msg.value;}function withdraw(uint256 amount) external {// 检查require(balances[msg.sender] >= amount, "Insufficient balance");// 生效balances[msg.sender] -= amount;// 交互(bool success, ) = msg.sender.call{value: amount}("");require(success, "Transfer failed");}
}
3. 访问控制
3.1 角色管理
contract RoleBasedAccess {using EnumerableSet for EnumerableSet.AddressSet;mapping(bytes32 => EnumerableSet.AddressSet) private roles;event RoleGranted(bytes32 indexed role, address indexed account);event RoleRevoked(bytes32 indexed role, address indexed account);modifier onlyRole(bytes32 role) {require(hasRole(role, msg.sender), "Unauthorized");_;}function hasRole(bytes32 role,address account) public view returns (bool) {return roles[role].contains(account);}function grantRole(bytes32 role,address account) external onlyRole(DEFAULT_ADMIN_ROLE) {if (roles[role].add(account)) {emit RoleGranted(role, account);}}function revokeRole(bytes32 role,address account) external onlyRole(DEFAULT_ADMIN_ROLE) {if (roles[role].remove(account)) {emit RoleRevoked(role, account);}}
}
3.2 权限代理
contract DelegatedAccess {mapping(address => mapping(address => bool)) private delegates;event DelegateChanged(address indexed delegator,address indexed delegatee,bool status);function setDelegate(address delegatee, bool status) external {delegates[msg.sender][delegatee] = status;emit DelegateChanged(msg.sender, delegatee, status);}function isDelegate(address delegator,address delegatee) public view returns (bool) {return delegates[delegator][delegatee];}modifier onlyDelegateOrOwner(address owner) {require(msg.sender == owner || isDelegate(owner, msg.sender),"Not authorized");_;}
}
4. 数据验证
4.1 输入验证
contract InputValidation {uint256 public constant MAX_ARRAY_LENGTH = 100;uint256 public constant MAX_VALUE = 1e20;function validateArrayInput(uint256[] calldata data) internal pure {require(data.length > 0, "Empty array");require(data.length <= MAX_ARRAY_LENGTH, "Array too long");for (uint i = 0; i < data.length; i++) {require(data[i] <= MAX_VALUE, "Value too large");if (i > 0) {require(data[i] >= data[i-1], "Not sorted");}}}function validateAddress(address addr) internal pure {require(addr != address(0), "Zero address");require(addr.code.length == 0, "Contract address not allowed");}
}
4.2 状态验证
contract StateValidation {enum State { Inactive, Active, Paused, Ended }State public currentState;modifier inState(State requiredState) {require(currentState == requiredState, "Invalid state");_;}function validateTransition(State newState) internal view {if (currentState == State.Inactive) {require(newState == State.Active, "Invalid transition");} else if (currentState == State.Active) {require(newState == State.Paused || newState == State.Ended,"Invalid transition");}}
}
5. 签名验证
5.1 EIP712 签名
contract EIP712Verifier {bytes32 private DOMAIN_SEPARATOR;struct EIP712Domain {string name;string version;uint256 chainId;address verifyingContract;}constructor(string memory name, string memory version) {DOMAIN_SEPARATOR = keccak256(abi.encode(keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),keccak256(bytes(name)),keccak256(bytes(version)),block.chainid,address(this)));}function verifySignature(bytes32 hash,bytes memory signature) internal view returns (address) {bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hash));return ecrecover(digest, signature[0], signature[1], signature[2]);}
}
5.2 签名重放防护
contract ReplayProtection {mapping(bytes32 => bool) private usedSignatures;function isSignatureUsed(bytes32 hash) public view returns (bool) {return usedSignatures[hash];}function markSignatureAsUsed(bytes32 hash) internal {require(!usedSignatures[hash], "Signature already used");usedSignatures[hash] = true;}function validateSignature(bytes32 hash,bytes memory signature,uint256 deadline) internal view returns (address) {require(block.timestamp <= deadline, "Signature expired");require(!isSignatureUsed(hash), "Signature already used");return verifySignature(hash, signature);}
}
6. 紧急响应
6.1 紧急停止
contract EmergencyStop {bool public stopped;address public guardian;modifier whenNotStopped() {require(!stopped, "Contract is stopped");_;}modifier whenStopped() {require(stopped, "Contract is not stopped");_;}function toggleStop() external {require(msg.sender == guardian, "Not authorized");stopped = !stopped;emit EmergencyToggled(stopped);}function emergencyWithdraw() external whenStopped {require(msg.sender == guardian, "Not authorized");// 执行紧急提款逻辑}
}
6.2 漏洞修复
contract UpgradeableSecurityFix {address public implementation;address public admin;function upgrade(address newImplementation) external {require(msg.sender == admin, "Not authorized");require(newImplementation.code.length > 0, "Not a contract");// 验证新实现是否兼容require(IUpgradeable(newImplementation).supportsInterface(0x01ffc9a7),"Incompatible implementation");implementation = newImplementation;emit Upgraded(newImplementation);}
}
7. 审计和测试
7.1 自动化测试
const { expect } = require("chai");
const { ethers } = require("hardhat");describe("SecurityTests", function() {let contract;let owner;let attacker;beforeEach(async function() {const Contract = await ethers.getContractFactory("SecureContract");[owner, attacker] = await ethers.getSigners();contract = await Contract.deploy();});it("Should prevent reentrancy attacks", async function() {await expect(contract.connect(attacker).withdraw()).to.be.revertedWith("Reentrant call");});it("Should validate access control", async function() {await expect(contract.connect(attacker).adminFunction()).to.be.revertedWith("Not authorized");});
});
7.2 形式化验证
/// @notice Invariant: total supply should always equal sum of balances
/// @custom:invariant totalSupply == sum(balances)
contract VerifiedToken {mapping(address => uint256) public balances;uint256 public totalSupply;function transfer(address to, uint256 amount) external {require(balances[msg.sender] >= amount, "Insufficient balance");balances[msg.sender] -= amount;balances[to] += amount;assert(balances[msg.sender] <= totalSupply);assert(balances[to] <= totalSupply);}
}
8. 相关资源
- 智能合约安全最佳实践
- OpenZeppelin 安全博客
- 以太坊安全工具集
- Slither 静态分析工具
- MythX 安全平台
相关文章:
智能合约安全指南 [特殊字符]️
智能合约安全指南 🛡️ 1. 安全基础 1.1 常见漏洞类型 重入攻击整数溢出权限控制缺陷随机数漏洞前后运行攻击签名重放 1.2 安全开发原则 最小权限原则检查-生效-交互模式状态机安全失败保护机制 2. 重入攻击防护 2.1 基本防护模式 contract ReentrancyGuarde…...
【Python项目】基于Python的书籍售卖系统
【Python项目】基于Python的书籍售卖系统 技术简介:采用Python技术、MYSQL数据库等实现。 系统简介:书籍售卖系统是一个基于B/S结构的在线图书销售平台,主要分为前台和后台两部分。前台系统功能模块分为(1)用户中心模…...
【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(未成功版)
【Linux】【网络】UDP打洞–>不同子网下的客户端和服务器通信(未成功版) 上次说基于UDP的打洞程序改了五版一直没有成功,要写一下问题所在,但是我后续又查询了一些资料,成功实现了,这次先写一下未成功的…...
(1)udp双向通信(2)udp实现文件复制(3)udp实现聊天室
一.udp双向通信 1.fork进程实现双向通信 【1】head.h 【2】client客户端 (1)父进程从键盘获取字符串 (2)输入quit,发送结束子进程信号 (3)exit退出父进程 (1)子进程接受…...
c高级第五天
1> 在终端提示输入一个成绩,通过shell判断该成绩的等级 [90,100] : A [80, 90) : B [70, 80) : C [60, 70) : D [0, 60) : 不及格 #!/bin/bash# 提示用户输入成绩 read -p "请输入成绩(0-100):" score# 判断成…...
【JQuery—前端快速入门】JQuery 操作元素
JQuery 操作元素 1. 获取/修改元素内容 三个简单的获取元素的方法: 这三个方法即可以获取元素的内容,又可以设置元素的内容. 有参数时,就进行元素的值设置,没有参数时,就进行元素内容的获取. 接下来,我们需…...
深度学习-139-RAG技术之Agentic Chunking分块技术的工作原理及简单实现
文章目录 1 传统分块的问题2 Agentic Chunking的工作原理3 Agentic Chunking怎么实现3.1 Propositioning文本3.1.1 大语言模型3.1.2 官方提示词模板3.1.3 抽取链3.2 使用LLM Agent创建文本块3.2.1 创建新文本块3.2.2 将proposition添加到文本块3.2.3 将proposition推送到合适的…...
BambuStudio学习笔记:Flow 类
Flow 类文档 概述 Flow 类用于管理3D打印过程中的挤出流程参数计算,包括挤出宽度、间距、流量等核心参数。支持桥梁模式、不同流程角色配置,提供多种流量计算方式。 头文件 #ifndef slic3r_Flow_hpp_ #define slic3r_Flow_hpp_ // ... #endif枚举类型…...
标签的ref属性 vue中为什么不用id标记标签
标签的ref属性 vue中为什么不用id标记标签 假设有一对父子组件,如果父组件和子组件中存在id相同的标签,会产生冲突。通过id获取标签会获取到先加载那个标签。 标签的ref属性的用法 在父组件App中,引入了子组件Person。 并使用ref标记了Pe…...
7.1.1 计算机网络的组成
文章目录 物理组成功能组成工作方式完整导图 物理组成 计算机网络是将分布在不同地域的计算机组织成系统,便于相互之间资源共享、传递信息。 计算机网络的物理组成包括硬件和软件。硬件中包含主机、前端处理器、连接设备、通信线路。软件中包含协议和应用软件。 功…...
IDEA 接入 Deepseek
在本篇文章中,我们将详细介绍如何在 JetBrains IDEA 中使用 Continue 插件接入 DeepSeek,让你的 AI 编程助手更智能,提高开发效率。 一、前置准备 在开始之前,请确保你已经具备以下条件: 安装了 JetBrains IDEA&…...
mapbox基础,使用点类型geojson加载symbol符号图层,用于标注文字
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️symbol符号图层样式二、🍀使用点类型…...
STM32---FreeRTOS中断管理试验
一、实验 实验目的:学会使用FreeRTOS的中断管理 创建两个定时器,一个优先级为4,另一个优先级为6;注意:系统所管理的优先级范围 :5~15 现象:两个定时器每1s,打印一段字符串&#x…...
Python 网络爬虫教程与案例详解
Python 网络爬虫教程与案例详解 在当今数字化时代,数据的价值愈发凸显。Python 作为一门强大的编程语言,在数据获取领域有着广泛的应用,其中网络爬虫便是一项重要的技术。网络爬虫能够自动从网页中提取所需数据,极大地提高了数据…...
HTTP 状态代码 501 502 问题
问题 单个客户端有时会出现 报错 501 或 502 如下: System.Net.Http.HttpRequestException: Response status code does not indicate success: 501 (Not Implemented) 分析 可以排除 服务器无法处理的问题(测试发现 一个客户端报错,不会影响…...
React 之 Redux 第二十八节 学习目标与规划大纲及概要讲述
接下来 开始Redux 全面详细的文档输出,主要基于一下几个方面,欢迎大家补充指正 一、Redux 基础概念 为什么需要 Redux? 前端状态管理的挑战(组件间通信、状态共享) Redux 解决的问题:集中式、可预测的状态…...
visual studio 2022 手工写一个简单的MFC程序
书籍:《Visual C 2017从入门到精通》的2.1.2 MFC方式中2.手工写一个简单的MFC程序 环境:visual studio 2022 内容:手工写一个简单的MFC程序 1.文件->新建->项目 2.根据以下步骤选择Windows桌面向导 3.输入项目名,选择保…...
GaussDB自带诊断工具实战指南
一、引言 GaussDB是一种分布式的关系型数据库。在数据库运维中,快速定位性能瓶颈、诊断故障是保障业务连续性的关键。GaussDB内置了多种诊断工具,结合日志分析、执行计划解析和实时监控功能,帮助开发者与运维人员高效解决问题。本文深入讲解…...
python GUI之实现一个自定义的范围滑块控件:QRangeSlider
在图形用户界面(GUI)开发中,滑块控件是一种常用于选择数值范围的交互元素。然而,很多时候默认的滑块控件无法满足复杂的交互需求,例如同时选择一个范围的起始值和结束值。为此,实现了一个自定义的范围滑块控…...
测试用例总结
一、通用测试用例八要素 1、用例编号; 2、测试项目; 3、测试标题; 4、重要级别; 5、预置条件; 6、测试输入; 7、操作步骤; 8、预期输出 二、具体分析通…...
深度学习之图像学习知识点
数据增广: 数据增广是深度学习中常用的技巧之一,主要用于增加训练数据集,让数据集尽可能的多样化,使得训练的模型具有更强的泛化能力,目前数据增广主要包括:水平/垂直翻转,旋转,缩放…...
vulnhub靶场之【digitalworld.local系列】的development靶机
前言 靶机:digitalworld.local-devt-improved,IP地址为192.168.10.10 攻击:kali,IP地址为192.168.10.6 kali采用VMware虚拟机,靶机选择使用VMware打开文件,都选择桥接网络 这里官方给的有两种方式&…...
C语言---猜数字游戏
猜数字游戏代码 #include <stdio.h> #include <time.h> #include <stdlib.h>void meun() {printf("**********************\n");printf("******* 1.play *******\n");printf("******* 0.quit *******\n");printf("*****…...
C#中泛型的协变和逆变
协变: 在泛型接口中,使用out关键字可以声明协变。这意味着接口的泛型参数只能作为返回类型出现,而不能作为方法的参数类型。 示例:泛型接口中的协变 假设我们有一个基类Animal和一个派生类Dog: csharp复制 public…...
Select 下拉菜单选项分组
使用<select>元素创建下拉菜单,并使用 <optgroup> 元素对选项进行分组。<optgroup> 元素允许你将相关的 <option> 元素分组在一起,并为每个分组添加一个标签。 <form action"#" method"post"><la…...
文件上传漏洞详细利用流程
一、了解基本术语 1、后门 像房子一样,前门后门都可以进出房子,而较之前门,后门更具有隐蔽性。电脑技术中的后门是抽象概念,意指隐蔽性高或不常用的,区别于常规操作所使用的一种出入口。现金网络后门形形色色&#x…...
蓝桥与力扣刷题(蓝桥 旋转)
题目:图片旋转是对图片最简单的处理方式之一,在本题中,你需要对图片顺时针旋转 90 度。 我们用一个 nm的二维数组来表示一个图片,例如下面给出一个 34 的 图片的例子: 1 3 5 7 9 8 7 6 3 5 9 7 这个图片顺时针旋转…...
transformer架构解析{掩码,(自)注意力机制,多头(自)注意力机制}(含代码)-3
目录 前言 掩码张量 什么是掩码张量 掩码张量的作用 生成掩码张量实现 注意力机制 学习目标 注意力计算规则 注意力和自注意力 注意力机制 注意力机制计算规则的代码实现 多头注意力机制 学习目标 什么是多头注意力机制 多头注意力计算机制的作用 多头注意力机…...
使用DiskGenius工具来实现物理机多硬盘虚拟化迁移
使用DiskGenius工具来实现物理机多硬盘虚拟化迁移 概述准备工作注意事项实操过程记录1、Win7虚拟机,安装有两个硬盘(硬盘0和硬盘1),各分了一个区,磁盘2是一块未使用的磁盘2、运行DiskGenius程序,记录现有各…...
iOS安全和逆向系列教程 第5篇 iOS基础开发知识速览 - 理解你要逆向的目标
iOS安全和逆向系列教程 第5篇 iOS基础开发知识速览 - 理解你要逆向的目标 正如上一篇文章结尾所预告的,在完成环境搭建后,我们需要了解iOS开发的基础知识。这不是要求你成为一名iOS开发者,而是为了让你在逆向分析过程中能够理解应用的代码结…...
