【Solidity】安全与校验
信息传输
发送方 A:
-
计算消息 message 的哈希值 H:
hash(message) = H
-
私钥 privateKey ➕ 哈希值 H 🟰 签名 signature:
signature = sign(H, privateKey)
-
将消息 message 和签名 signature 发送给 B
接收方 B:
-
计算消息 message 的哈希值 H1:
hash(message) = H1
-
公钥 publicKey ➕ 签名 signature 🟰 H2:
H2 = verify(signature, publicKey)
-
比较 H1 和 H2,如果相等 则说明消息未被篡改且确实来自 A
Keccak256 哈希函数
contract HashFunc {function hash(string memory _testString,uint _testUint) public pure returns (bytes32) {// 先对数据进行编码, 再用 keccak256 加密return keccak256(abi.encodePacked(_testString, _testUint));}
}
encodePacked 方法可以对多个参数进行编码,并压缩编码后的结果,节省 gas 费用。但某些情况下会导致哈希碰撞(哈希冲突)。
为了避免哈希碰撞,可以使用 encode 方法,它不会压缩编码结果,但会消耗更多 gas。
contract HashFunc {function hash(string memory _testString,uint _testUint) public pure returns (bytes32) {// 使用 encode 方法避免哈希碰撞return keccak256(abi.encode(_testString, _testUint));}
}
除了使用 encode 方法,我们还可以在 encodePacked 的入参之间再插入一个参数,这样也能避免哈希碰撞。
contract HashFunc {function hash(string memory _string1,uint _uint, // 用来避免哈希碰撞的参数string memory _string2) public pure returns (bytes32) {// 在 encodePacked 的入参之间再插入一个参数,避免哈希碰撞return keccak256(abi.encodePacked(_string1, _uint, _string2));}
}
签名与验证
contract VerifySig {// 将一个 65 字节长的签名拆分成 r、s 和 v 三个部分function split(bytes memory _signature) internal pure returns (bytes32 r, bytes32 s, uint8 v) {require(_signature.length == 65, "invalid signature length");assembly {// 从 _signature 的第 32 字节开始加载 32 字节的数据, 并将其赋值给 r// 这是因为前 32 字节是 _signature 的长度信息r := mload(add(_signature, 32))// 从 _signature 的第 64 字节开始加载 32 字节的数据, 并将其赋值给 ss := mload(add(_signature, 64))// 从 _signature 的第 96 字节开始加载 32 字节的数据, 并取其第一个字节给 vv := byte(0, mload(add(_signature, 96)))}}// 计算给定消息的哈希值function getMessageHash(string memory _message) public pure returns (bytes32) {return keccak256(abi.encodePacked(_message));}// 生成一个符合以太坊签名标准的消息哈希值function getEthSignedMessageHash(bytes32 _messageHash) public pure returns (bytes32) {returnkeccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32",// 这是一个固定的前缀, 用于防止签名重用攻击// 这个前缀告诉以太坊客户端这是一个签名消息, 而不是交易或其他数据// \x19 表示消息的长度; 32 表示消息哈希的长度为 32 字节_messageHash));}// 从签名中恢复出签名者的地址function recover(bytes32 _ethSignedMessageHash,bytes memory _signature) public pure returns (address) {(bytes32 r, bytes32 s, uint8 v) = split(_signature);return ecrecover(_ethSignedMessageHash, v, r, s);}// 验证消息的有效性 (签名者是否正确、消息是否被篡改)function verify(address _signer,string memory _message,bytes memory _signature) public pure returns (bool) {bytes32 messageHash = getMessageHash(_message);bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);return recover(ethSignedMessageHash, _signature) == _signer;}
}
部署合约并测试:
模拟发送方 A:
-
将要发送的消息作为参数传入 getMessageHash 方法,得到消息的哈希值 H,这里以字符串 “hello” 为例
-
F12 打开控制台,执行
ethereum.enable()
;查看 Promise,若为 fulfilled 状态则说明 MetaMask 已连接,可查看 Promise 结果得到 MetaMask 的账号地址(需要先安装 MetaMask 插件并登录) -
执行
ethereum.request({ method: "personal_sign", params: [步骤 2 得到的 MetaMask 账号地址, 步骤 1 得到的哈希值 H] })
,会弹出签名框,点击 sign 进行签名;查看 Promise,若为 fulfilled 状态则说明签名成功,可查看 Promise 结果得到签名 signature -
假设 A 将步骤 3 得到的签名 signature 和消息 “hello” 发送给了 B
模拟接收方 B:
-
将收到的消息 “hello” 作为参数传入 getMessageHash 方法,得到消息的哈希值
-
将步骤 1 得到的哈希值作为参数传入 getEthSignedMessageHash 方法,得到符合以太坊签名标准的消息哈希值 H1
-
将步骤 2 得到的消息哈希值和收到的签名 signature 作为参数传入 recover 方法,得到签名者的地址;比对是否为 A 步骤 2 得到的 MetaMask 账号地址,如果不一致 则说明信息被篡改 / 消息不是来自 A
访问控制
contract AccessControl {// 定义两个角色bytes32 public constant ROLE_ADMIN =keccak256(abi.encodePacked("ROLE_ADMIN"));bytes32 public constant ROLE_USER =keccak256(abi.encodePacked("ROLE_USER"));// 定义一个双重映射, 用于管理 "角色 - 用户 - 权限"mapping(bytes32 => mapping(address => bool)) public roles;// 分配权限function _grantRole(bytes32 _role, address _account) internal {roles[_role][_account] = true;}// 撤销权限function _revokeRole(bytes32 _role, address _account) internal {roles[_role][_account] = false;}// 构造函数constructor() {_grantRole(ROLE_ADMIN, msg.sender);}// 函数装饰器, 限制只有管理员才能调用modifier onlyAdmin() {require(roles[ROLE_ADMIN][msg.sender],"AccessControl: sender must be an admin to perform this action");_;}// 分配权限 (外部使用, 只有管理员才能调用)function grantUserRole(address _account) public onlyAdmin {_grantRole(ROLE_USER, _account);}// 撤销权限 (外部使用, 只有管理员才能调用)function revokeUserRole(address _account) public onlyAdmin {_revokeRole(ROLE_USER, _account);}
}
-
部署合约,部署者将成为管理员
-
获取编辑器地址和 ROLE_ADMIN 的哈希值,填入 roles 中查看权限,此处应为 true
-
更新编辑器地址,获取新的编辑器地址和 ROLE_USER 的哈希值,填入 roles 中查看权限,此处应为 false
-
使用管理员地址调用 grantUserRole 方法,并传入新的编辑器地址作为参数,授权新的编辑器地址为 ROLE_USER
-
获取新的编辑器地址和 ROLE_USER 的哈希值,填入 roles 中查看权限,此处应为 true
-
使用管理员地址调用 revokeUserRole 方法,并传入新的编辑器地址作为参数,取消新的编辑器地址的 ROLE_USER 权限
-
获取新的编辑器地址和 ROLE_USER 的哈希值,填入 roles 中查看权限,此处应为 false
-
不使用管理员地址调用 grantUserRole 方法,会报错
相关文章:
【Solidity】安全与校验
信息传输 发送方 A: 计算消息 message 的哈希值 H:hash(message) H 私钥 privateKey ➕ 哈希值 H 🟰 签名 signature:signature sign(H, privateKey) 将消息 message 和签名 signature 发送给 B 接收方 B: 计算…...

黑神话悟空四十二项修改器 v1.0
软件简介 黑神话悟空四十二项修改器由风灵月影精心打磨,为《黑神话悟空》这款备受瞩目的游戏量身定制。这款修改器界面简洁、体积小巧、功能强大,它致力于为玩家提供便捷的游戏体验,让您能够根据个人喜好和需求,轻松调整游戏内的…...

RM电控RTOS
OS即(operating system)操作系统,比如我们常用的windows系统,mac系统,android系统,ios系统,linux系统等,都属于操作系统。操作系统的本质是一个特殊的软件,它直接管理硬件…...

Arduino开源四足蜘蛛机器人制作教程
视频教程:手把手叫你做四足蜘蛛机器人——1零件介绍_哔哩哔哩_bilibili 一、项目介绍 1.1 项目介绍 Arduino主控,图形化编程,趣味学习 Arduino nano开发板舵机扩展底板 4.8V可充电电池,支持Arduino C语言编程和米思齐图形化编程…...

【Axure高保真原型】中继器表格——标签使用情况案例
今天和大家分享中继器表格——标签使用情况案例的原型模板,效果包括: 模糊搜索——输入标签编号或者标签名称,可以快速查找对应的数据 排序——点击排序按钮,可以按升序或降序排列 分页——点击上拉列表,可以选择表格…...
ABAP字符串反转 and 寻找字符所在位置 and 根据数量汇总时把数量转为非数值类型
1.字符串反转 and 寻找字符所在位置 LOOP AT gt_wlmc ASSIGNING FIELD-SYMBOL(<fs_wlmc>). "遍历内表<fs_wlmc>-matnr <fs_wlmc>-matnr(8).DATA: l_output TYPE char50,v_off2 TYPE i,str TYPE i,str2 TYPE i.CALL FUNCTION STRING_REVERS…...
【机器学习第十二章——计算学习理论】
机器学习第十二章——计算学习理论 12.计算学习理论12.1 基础知识12.1 可能学习近似正确假设(PAC)12.3 有限假设空间12.4 VC维 12.计算学习理论 12.1 基础知识 从理论上刻画了若干类型的机器学习问题中的困难和若干类型的机器学习算法的能力 这个理论要…...
Docker私人学习笔记
俗话说“好记性不如烂笔头”,编程的海洋如此的浩大,养成做笔记的习惯是成功的一步! 此笔记主要是antlr4.13版本的笔记,并且笔记都是博主自己一字一字编写和记录,有错误的地方欢迎大家指正。 一、基础概念:…...
谷粒商城实战笔记-233~235-商城业务-认证服务-单点登录流程-原理
文章目录 一,场景二,单点登录流程 一,场景 包含以下三节的内容: 一,233-商城业务-认证服务-单点登录流程-1二,233-商城业务-认证服务-单点登录流程-2三,233-商城业务-认证服务-单点登录流程-3…...
机器学习在旅游业的革新之旅
机器学习在旅游业的革新之旅 随着科技的飞速发展,尤其是人工智能(AI)技术的广泛应用,各个行业都迎来了前所未有的变革。其中,旅游业作为全球经济的重要支柱之一,更是受益匪浅。机器学习(Machin…...

OpenCTI:开源网络威胁情报平台
OpenCTI 是一个开源平台,旨在帮助组织管理其网络威胁情报 (CTI) 数据和可观察数据。 该平台由 Filigran 开发,使用基于 STIX2 标准的知识模式构建数据。 它采用现代 Web 应用程序架构,配备 GraphQL API 和用户友好的前端。 OpenCTI 与 MIS…...
linux shell 脚本 let 数学计算
linux shell 脚本 let 数学计算 http://www.codebaoku.com/it-shell/ let命令中的算术表达式必须用双引号括起来,以避免解释器对特殊字符进行处理。 在变量的计算中,不需要使用$符号来表示变量, #!/bin/shweek_daydate %u echo $week_day…...

mp3和mp4的区别是什么?怎么把mp3转成mp4?(全)
在生活中我们或多或少会听到“mp3”和“mp4”,那么什么是mp3和mp4呢?mp3和mp4的区别是什么?mp3是一种音频压缩技术,旨在在不显著牺牲音质的前提下减小音频文件的体积,使其适用于音乐和其他音频内容的存储与传输。相比之…...
合并params和query参数
场景:三级分类只有query参数,搜索框使用params参数。为了解决这个问题,文中在typeNav的index.vue和Head/index.vue分别进行了判断和处理,确保在不同的路径下合并params和query参数能正确合并并传递。 如何当点击联动框时跳转到se…...

[数据集][目标检测]工程机械车辆检测数据集VOC+YOLO格式3189张10类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3189 标注数量(xml文件个数):3189 标注数量(txt文件个数):3189 标注…...
构建域名服务器-BIND:Linux端的安装过程及配置文件详解
文章目录 构建域名服务器工具-BINDBIND的安装BIND配置文件详解1. /etc/named.conf:2. /etc/named.rfc1912.zones:3. /var/named/named.localhost:4./etc/logrotate.d/named5./etc/named.iscdlv.key6./etc/named.root.key7./etc/rndc.conf8./e…...
linux查询目录文件基础操作
基础命令 展示所有目录 ls 长格式列出(显示文件权限、所有者、大小和最后修改时间): ls -l 忽略大小写查询 ls | grep -i name 查找特定名称的文件: find /path/to/search -name "filename" 忽略大小写查找文件&#…...

搭建TestBench,收藏这几条基本框架就够了
Verilog功能模块HDL设计完成后,并不代表设计工作的结束,还需要对设计进行进一步的仿真验证。掌握验证的方法,即如何调试自己的程序非常重要。在RTL逻辑设计中,要学会根据硬件逻辑来写测试程序即写Testbench。Verilog测试平台是一个…...
怎么利用住宅代理提高数据抓取效率
在大数据时代,数据抓取已经是从互联网收集数据的关键手段,得到了广泛的应用。不论是网络营销、电商平台、或者是新闻网站,数据抓取都可以帮助企业或者是个人收集到大量的数据。但是随着反爬虫技术的不断发展,传统的爬虫方法已经不…...
c#中的ManuaResetEvent
在C#中,ManualResetEvent 是一个同步事件,用于线程间通信。它允许一个或多个等待的线程等待某个事件的发生。当事件被设置为已发生(或称为“信号”)状态时,所有等待的线程都会被释放,并且可以继续执行。 以…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...