当前位置: 首页 > news >正文

【Solidity】安全与校验

信息传输

发送方 A:

  1. 计算消息 message 的哈希值 H:hash(message) = H

  2. 私钥 privateKey ➕ 哈希值 H 🟰 签名 signature:signature = sign(H, privateKey)

  3. 将消息 message 和签名 signature 发送给 B

接收方 B:

  1. 计算消息 message 的哈希值 H1:hash(message) = H1

  2. 公钥 publicKey ➕ 签名 signature 🟰 H2:H2 = verify(signature, publicKey)

  3. 比较 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:

  1. 将要发送的消息作为参数传入 getMessageHash 方法,得到消息的哈希值 H,这里以字符串 “hello” 为例

  2. F12 打开控制台,执行 ethereum.enable();查看 Promise,若为 fulfilled 状态则说明 MetaMask 已连接,可查看 Promise 结果得到 MetaMask 的账号地址(需要先安装 MetaMask 插件并登录)

  3. 执行 ethereum.request({ method: "personal_sign", params: [步骤 2 得到的 MetaMask 账号地址, 步骤 1 得到的哈希值 H] }),会弹出签名框,点击 sign 进行签名;查看 Promise,若为 fulfilled 状态则说明签名成功,可查看 Promise 结果得到签名 signature

  4. 假设 A 将步骤 3 得到的签名 signature 和消息 “hello” 发送给了 B

模拟接收方 B:

  1. 将收到的消息 “hello” 作为参数传入 getMessageHash 方法,得到消息的哈希值

  2. 将步骤 1 得到的哈希值作为参数传入 getEthSignedMessageHash 方法,得到符合以太坊签名标准的消息哈希值 H1

  3. 将步骤 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);}
}
  1. 部署合约,部署者将成为管理员

  2. 获取编辑器地址和 ROLE_ADMIN 的哈希值,填入 roles 中查看权限,此处应为 true

  3. 更新编辑器地址,获取新的编辑器地址和 ROLE_USER 的哈希值,填入 roles 中查看权限,此处应为 false

  4. 使用管理员地址调用 grantUserRole 方法,并传入新的编辑器地址作为参数,授权新的编辑器地址为 ROLE_USER

  5. 获取新的编辑器地址和 ROLE_USER 的哈希值,填入 roles 中查看权限,此处应为 true

  6. 使用管理员地址调用 revokeUserRole 方法,并传入新的编辑器地址作为参数,取消新的编辑器地址的 ROLE_USER 权限

  7. 获取新的编辑器地址和 ROLE_USER 的哈希值,填入 roles 中查看权限,此处应为 false

  8. 不使用管理员地址调用 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 可能学习近似正确假设&#xff08;PAC&#xff09;12.3 有限假设空间12.4 VC维 12.计算学习理论 12.1 基础知识 从理论上刻画了若干类型的机器学习问题中的困难和若干类型的机器学习算法的能力 这个理论要…...

Docker私人学习笔记

俗话说“好记性不如烂笔头”&#xff0c;编程的海洋如此的浩大&#xff0c;养成做笔记的习惯是成功的一步&#xff01; 此笔记主要是antlr4.13版本的笔记&#xff0c;并且笔记都是博主自己一字一字编写和记录&#xff0c;有错误的地方欢迎大家指正。 一、基础概念&#xff1a;…...

谷粒商城实战笔记-233~235-商城业务-认证服务-单点登录流程-原理

文章目录 一&#xff0c;场景二&#xff0c;单点登录流程 一&#xff0c;场景 包含以下三节的内容&#xff1a; 一&#xff0c;233-商城业务-认证服务-单点登录流程-1二&#xff0c;233-商城业务-认证服务-单点登录流程-2三&#xff0c;233-商城业务-认证服务-单点登录流程-3…...

机器学习在旅游业的革新之旅

机器学习在旅游业的革新之旅 随着科技的飞速发展&#xff0c;尤其是人工智能&#xff08;AI&#xff09;技术的广泛应用&#xff0c;各个行业都迎来了前所未有的变革。其中&#xff0c;旅游业作为全球经济的重要支柱之一&#xff0c;更是受益匪浅。机器学习&#xff08;Machin…...

OpenCTI:开源网络威胁情报平台

OpenCTI 是一个开源平台&#xff0c;旨在帮助组织管理其网络威胁情报 (CTI) 数据和可观察数据。 该平台由 Filigran 开发&#xff0c;使用基于 STIX2 标准的知识模式构建数据。 它采用现代 Web 应用程序架构&#xff0c;配备 GraphQL API 和用户友好的前端。 OpenCTI 与 MIS…...

linux shell 脚本 let 数学计算

linux shell 脚本 let 数学计算 http://www.codebaoku.com/it-shell/ let命令中的算术表达式必须用双引号括起来&#xff0c;以避免解释器对特殊字符进行处理。 在变量的计算中&#xff0c;不需要使用$符号来表示变量&#xff0c; #!/bin/shweek_daydate %u echo $week_day…...

mp3和mp4的区别是什么?怎么把mp3转成mp4?(全)

在生活中我们或多或少会听到“mp3”和“mp4”&#xff0c;那么什么是mp3和mp4呢&#xff1f;mp3和mp4的区别是什么&#xff1f;mp3是一种音频压缩技术&#xff0c;旨在在不显著牺牲音质的前提下减小音频文件的体积&#xff0c;使其适用于音乐和其他音频内容的存储与传输。相比之…...

合并params和query参数

场景&#xff1a;三级分类只有query参数&#xff0c;搜索框使用params参数。为了解决这个问题&#xff0c;文中在typeNav的index.vue和Head/index.vue分别进行了判断和处理&#xff0c;确保在不同的路径下合并params和query参数能正确合并并传递。 如何当点击联动框时跳转到se…...

[数据集][目标检测]工程机械车辆检测数据集VOC+YOLO格式3189张10类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3189 标注数量(xml文件个数)&#xff1a;3189 标注数量(txt文件个数)&#xff1a;3189 标注…...

构建域名服务器-BIND:Linux端的安装过程及配置文件详解

文章目录 构建域名服务器工具-BINDBIND的安装BIND配置文件详解1. /etc/named.conf&#xff1a;2. /etc/named.rfc1912.zones&#xff1a;3. /var/named/named.localhost&#xff1a;4./etc/logrotate.d/named5./etc/named.iscdlv.key6./etc/named.root.key7./etc/rndc.conf8./e…...

linux查询目录文件基础操作

基础命令 展示所有目录 ls 长格式列出&#xff08;显示文件权限、所有者、大小和最后修改时间&#xff09;&#xff1a; ls -l 忽略大小写查询 ls | grep -i name 查找特定名称的文件&#xff1a; find /path/to/search -name "filename" 忽略大小写查找文件&#…...

搭建TestBench,收藏这几条基本框架就够了

Verilog功能模块HDL设计完成后&#xff0c;并不代表设计工作的结束&#xff0c;还需要对设计进行进一步的仿真验证。掌握验证的方法&#xff0c;即如何调试自己的程序非常重要。在RTL逻辑设计中&#xff0c;要学会根据硬件逻辑来写测试程序即写Testbench。Verilog测试平台是一个…...

怎么利用住宅代理提高数据抓取效率

在大数据时代&#xff0c;数据抓取已经是从互联网收集数据的关键手段&#xff0c;得到了广泛的应用。不论是网络营销、电商平台、或者是新闻网站&#xff0c;数据抓取都可以帮助企业或者是个人收集到大量的数据。但是随着反爬虫技术的不断发展&#xff0c;传统的爬虫方法已经不…...

c#中的ManuaResetEvent

在C#中&#xff0c;ManualResetEvent 是一个同步事件&#xff0c;用于线程间通信。它允许一个或多个等待的线程等待某个事件的发生。当事件被设置为已发生&#xff08;或称为“信号”&#xff09;状态时&#xff0c;所有等待的线程都会被释放&#xff0c;并且可以继续执行。 以…...

EE trade:黄金投资的利弊与要点

黄金投资作为一种相对传统的投资途径&#xff0c;存在着特定的优势与风险。接下来详细剖析一下黄金投资的优缺点。 1、黄金投资的优点 有效对抗通货膨胀 在通货膨胀时期&#xff0c;黄金往往能有出色的表现&#xff0c;其价值通常会上升&#xff0c;如此一来便能够为投资者提…...

数据仓库模型评估的标准

面试中&#xff0c;肯定有数仓同学被问到&#xff1a;数据模型如何去评估、如何优化&#xff0c;那今天就聊一聊这个话题。 基本概念 模型&#xff1a;表达的是某一个主题、某一个业务过程&#xff0c;赋值业务价值&#xff0c;最终落地还是一个建表的过程 数仓模型&#xf…...

121231

实打实大苏打...

【机器学习】逻辑回归原理(极大似然估计,逻辑函数Sigmod函数模型详解!!!)

目录 &#x1f354; 逻辑回归应用场景 &#x1f354; 极大似然估计 2.1 为什么要有极大似然估计&#xff1f; 2.2 极大似然估计步骤 2.3 极大似然估计的例子 &#x1f354; Sigmod函数模型 3.1 逻辑斯特函数的由来 3.2 Sigmod函数绘图 3.3 进一步探究-加入线性回归 3…...

网络热门编程项目导学:黑马点评

本文作者&#xff1a;程序员鱼皮 免费编程学习 - 编程导航网&#xff1a;https://www.code-nav.cn 大家好&#xff0c;我是鱼皮。 之前已经给大家分享了三个全栈项目&#xff0c;比如瑞吉外卖什么的&#xff0c;这几个项目都是侧重于带大家学习框架的运用、以及一些简单的业务…...

如何在本地和远程删除 Git 分支?

如何在本地和远程删除 Git 分支&#xff1f; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社区主理人 擅长.n…...

08 STM32 DMA

DMA 协助CPU&#xff0c;完成数据转运工作。 两个程序&#xff1a; DMA数据转运&#xff0c;DMAAD多通道 DMA数据转运&#xff0c;将使用DMA&#xff0c;进行存储器到存储器的数据转运&#xff0c;也就是把一个数组里面的数据&#xff0c;复制到另一个数组里。 定义一个数组D…...

LLM之基于llama-index部署本地embedding与GLM-4模型并初步搭建RAG(其他大模型也可,附上ollma方式运行)

前言 日常没空&#xff0c;留着以后写 llama-index简介 官网&#xff1a;https://docs.llamaindex.ai/en/stable/ 简介也没空&#xff0c;以后再写 注&#xff1a;先说明&#xff0c;随着官方的变动&#xff0c;代码也可能变动&#xff0c;大家运行不起来&#xff0c;可以进…...

Python 异步爬虫:高效数据抓取的现代武器

标题&#xff1a;“Python 异步爬虫&#xff1a;高效数据抓取的现代武器” 在当今信息爆炸的时代&#xff0c;网络爬虫已成为数据采集的重要工具。然而&#xff0c;传统的同步爬虫在处理大规模数据时往往效率低下。本文将深入探讨如何使用 Python 实现异步爬虫&#xff0c;以提…...

【数据结构算法经典题目刨析(c语言)】使用数组实现循环队列(图文详解)

&#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏&#xff1a;数据结构经典题目刨析(c语言) 目录 一.题目描述 二.解题思路 1.循环队列的结构定义 2.队列初始化 3.判空 4.判满 5.入队列 6.出队列 7.取队首元素 8.取队尾元素 三.完整代码实…...