汕头网站建设和运营ie浏览器打不开建设银行网站

张小明 2026/1/13 16:36:26
汕头网站建设和运营,ie浏览器打不开建设银行网站,大学生兼职做网站,如何解决网站访问拥挤文章目录1. 设计模式概述1.1 什么是设计模式1.2 智能合约中的6个核心设计模式2. 访问控制模式2.1 为什么需要访问控制2.2 Ownable模式2.3 RBAC模式#xff08;基于角色的访问控制#xff09;2.4 使用OpenZeppelin的实现3. 提现模式3.1 传统做法的风险3.2 攻击合约示例3.3 安全…文章目录1. 设计模式概述1.1 什么是设计模式1.2 智能合约中的6个核心设计模式2. 访问控制模式2.1 为什么需要访问控制2.2 Ownable模式2.3 RBAC模式基于角色的访问控制2.4 使用OpenZeppelin的实现3. 提现模式3.1 传统做法的风险3.2 攻击合约示例3.3 安全方案1Pull Over Push模式3.5 结合重入锁4. 状态机模式4.1 什么是状态机4.2 ICO众筹示例4.3 适用场景1. 设计模式概述1.1 什么是设计模式在软件工程中设计模式是被反复使用的、经过实践验证的解决方案。它们不是具体的代码而是一种解决特定问题的思路和方法。设计模式的价值提高代码质量经过实践验证的解决方案减少常见错误提高代码可维护性加速开发不需要从零开始设计复用成熟的方案减少开发时间增强安全性模式通常考虑了安全因素避免常见的安全漏洞提高合约的可靠性便于协作团队成员都理解这些模式代码更容易理解和维护降低沟通成本1.2 智能合约中的6个核心设计模式在智能合约开发领域有6个核心的设计模式它们分别解决不同的问题访问控制模式解决权限管理问题确保只有授权者能执行敏感操作基础但至关重要提现模式解决资金转账的安全问题防止重入攻击确保资金安全转移状态机模式管理合约的生命周期规范状态转换流程适用于有明确阶段的场景代理模式实现合约升级分离数据和逻辑解决不可变性与升级需求的矛盾工厂模式批量部署相同类型的合约降低部署成本统一管理合约实例紧急停止模式风险控制机制快速暂停合约功能保护用户资产安全这些模式在实际项目中通常会组合使用共同构建安全可靠的智能合约系统。2. 访问控制模式访问控制模式是几乎所有合约都需要的基础模式。通过权限管理我们可以确保系统的安全性和完整性控制谁可以执行敏感操作。2.1 为什么需要访问控制设想一下如果一个合约没有任何访问控制会发生什么没有访问控制的危险// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// 没有访问控制的危险合约 contract UnsafeToken{mapping(addressuint256)public balances;uint256 public totalSupply;/** * notice 任何人都可以铸造代币 * dev 危险没有权限检查攻击者可以给自己铸造无限代币 */functionmint(address to, uint256 amount)public{balances[to]amount;totalSupplyamount;}/** * notice 任何人都可以销毁合约 * dev 危险没有权限检查任何人都可以销毁合约并提取资金 */functiondestroy()public{selfdestruct(payable(msg.sender));}}问题分析任何人都可以铸造代币攻击者可以给自己铸造无限代币代币价值会瞬间归零项目完全崩溃任何人都可以销毁合约攻击者可以销毁合约并提取所有资金用户资金全部丢失系统完全瘫痪无法审计和追踪不知道谁执行了什么操作无法追溯问题来源无法进行权限管理有了访问控制的好处确保只有授权者能执行敏感操作不同角色可以拥有不同的权限可以转移或撤销权限能够审计追踪所有的操作历史2.2 Ownable模式Ownable模式是最基础的访问控制实现。合约有一个owner地址所有关键操作都需要通过onlyOwner修饰符来检查调用者是否是owner。实现示例// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// Ownable模式简单的单所有者权限控制 contract OwnableToken{// 记录合约所有者 address public owner;mapping(addressuint256)public balances;uint256 public totalSupply;// 事件记录所有权转移 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);/** * notice 构造函数初始化owner * dev 部署合约时msg.sender成为owner */constructor(){ownermsg.sender;emit OwnershipTransferred(address(0), msg.sender);}/** * notice onlyOwner修饰符 * dev 只有owner可以调用被此修饰符修饰的函数 */ modifieronlyOwner(){require(msg.senderowner,Not owner);_;}/** * notice 铸造代币只有owner可以调用 * param to 接收者地址 * param amount 铸造数量 * dev 使用onlyOwner修饰符确保只有owner可以铸造 */functionmint(address to, uint256 amount)public onlyOwner{balances[to]amount;totalSupplyamount;}/** * notice 转移所有权 * param newOwner 新的所有者地址 * dev 只有当前owner可以转移所有权 */functiontransferOwnership(address newOwner)public onlyOwner{require(newOwner!address(0),Invalid owner);address oldOwnerowner;ownernewOwner;emit OwnershipTransferred(oldOwner, newOwner);}/** * notice 放弃所有权 * dev owner可以放弃所有权之后合约将无法升级或修改 */functionrenounceOwnership()public onlyOwner{address oldOwnerowner;owneraddress(0);emit OwnershipTransferred(oldOwner, address(0));}}Ownable模式的特点优点实现简单易于理解Gas成本低适合权限需求单一的场景缺点只有一个角色owner无法实现细粒度的权限控制不适合复杂的权限需求适用场景简单的代币合约权限需求单一的项目小型项目或原型2.3 RBAC模式基于角色的访问控制RBACRole-Based Access Control是更灵活的权限管理方式。OpenZeppelin提供了AccessControl合约允许我们定义多个角色每个函数可以指定需要的角色。实现示例// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// RBAC模式基于角色的访问控制 contract RBACToken{// 角色映射角色地址是否有权限 mapping(bytes32mapping(addressbool))private roles;mapping(addressuint256)public balances;uint256 public totalSupply;bool public paused;// 定义角色常量 // 使用keccak256确保角色标识符的唯一性 bytes32 public constant ADMIN_ROLEkeccak256(ADMIN_ROLE);bytes32 public constant MINTER_ROLEkeccak256(MINTER_ROLE);bytes32 public constant PAUSER_ROLEkeccak256(PAUSER_ROLE);bytes32 public constant BURNER_ROLEkeccak256(BURNER_ROLE);// 事件记录角色授予和撤销 event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);/** * notice 构造函数初始化管理员 * dev 部署者自动获得ADMIN_ROLE */constructor(){roles[ADMIN_ROLE][msg.sender]true;emit RoleGranted(ADMIN_ROLE, msg.sender, msg.sender);}/** * notice onlyRole修饰符 * param role 需要的角色 * dev 检查调用者是否拥有指定角色 */ modifier onlyRole(bytes32 role){require(roles[role][msg.sender],Access denied);_;}/** * notice 检查地址是否拥有角色 * param role 角色 * param account 地址 * return 是否拥有角色 */functionhasRole(bytes32 role, address account)public view returns(bool){returnroles[role][account];}/** * notice 授予角色 * param role 角色 * param account 地址 * dev 只有ADMIN可以授予角色 */functiongrantRole(bytes32 role, address account)public onlyRole(ADMIN_ROLE){require(!roles[role][account],Already has role);roles[role][account]true;emit RoleGranted(role, account, msg.sender);}/** * notice 撤销角色 * param role 角色 * param account 地址 * dev 只有ADMIN可以撤销角色 */functionrevokeRole(bytes32 role, address account)public onlyRole(ADMIN_ROLE){require(roles[role][account],Does not have role);roles[role][account]false;emit RoleRevoked(role, account, msg.sender);}/** * notice 铸造代币只有MINTER可以调用 * param to 接收者地址 * param amount 铸造数量 * dev 使用onlyRole(MINTER_ROLE)确保只有MINTER可以铸造 */functionmint(address to, uint256 amount)public onlyRole(MINTER_ROLE){require(!paused,Contract is paused);balances[to]amount;totalSupplyamount;}/** * notice 销毁代币只有BURNER可以调用 * param from 销毁者地址 * param amount 销毁数量 * dev 使用onlyRole(BURNER_ROLE)确保只有BURNER可以销毁 */functionburn(address from, uint256 amount)public onlyRole(BURNER_ROLE){require(balances[from]amount,Insufficient balance);balances[from]-amount;totalSupply -amount;}/** * notice 暂停合约只有PAUSER可以调用 * dev 暂停后mint等操作将无法执行 */functionpause()public onlyRole(PAUSER_ROLE){pausedtrue;}/** * notice 恢复合约只有PAUSER可以调用 * dev 恢复后合约功能恢复正常 */functionunpause()public onlyRole(PAUSER_ROLE){pausedfalse;}}RBAC模式的特点优点支持多个角色权限管理灵活可以实现细粒度的权限控制适合大型项目缺点实现相对复杂Gas成本稍高需要仔细设计角色体系适用场景大型DeFi协议需要多角色管理的项目复杂的权限需求2.4 使用OpenZeppelin的实现OpenZeppelin提供了经过充分审计的访问控制实现推荐直接使用// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// 导入OpenZeppelin的Ownableimportopenzeppelin/contracts/access/Ownable.sol;// 使用OpenZeppelin Ownable的代币合约 contract SecureToken is Ownable{mapping(addressuint256)public balances;uint256 public totalSupply;/** * notice 构造函数 * dev Ownable会自动将msg.sender设置为owner */ constructor()Ownable(){// owner已经在Ownable的构造函数中设置}/** * notice 铸造代币 * param to 接收者地址 * param amount 铸造数量 * dev 使用onlyOwner修饰符 */functionmint(address to, uint256 amount)external onlyOwner{balances[to]amount;totalSupplyamount;}}OpenZeppelin的优势经过充分审计被广泛使用提供完整的功能持续维护和更新推荐做法除非有特殊需求否则应该使用OpenZeppelin的标准实现而不是自己从零实现。3. 提现模式提现模式专门用于处理资金转账的安全问题。这个模式能够有效防止重入攻击确保资金的安全转移。3.1 传统做法的风险很多开发者会写出这样的代码先调用transfer或send转账给用户然后再更新用户的余额。这种写法有三大核心风险。不安全的实现// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// 存在重入漏洞的银行合约 contract VulnerableBank{mapping(addressuint256)public balances;/** * notice 存款函数 * dev 用户可以存入以太币 */functiondeposit()public payable{balances[msg.sender]msg.value;}/** * notice 提现函数存在重入漏洞 * dev 危险先转账后更新状态 */functionwithdraw()public{uint256 amountbalances[msg.sender];require(amount0,No balance);// 危险先转账 // 如果接收者是一个恶意合约它可以在receive函数中再次调用withdraw(bool success,)msg.sender.call{value: amount}();require(success,Transfer failed);// 危险后更新状态 // 如果发生重入此时余额还没有被清零攻击者可以再次提取 balances[msg.sender]0;}/** * notice 查询合约余额 */functiongetBalance()public view returns(uint256){returnaddress(this).balance;}}三大核心风险重入攻击风险如果接收者是一个恶意合约它可以在receive或fallback函数中再次调用withdraw由于余额还没有被清零攻击者可以反复提取资金2016年著名的The DAO攻击就是因为这个漏洞导致损失了5000万美元Gas不足导致转账失败如果transfer或send失败但用户余额已经被扣除就会导致用户资金被锁定在合约中用户无法取回资金影响其他用户如果某一笔转账失败可能会影响到其他用户的正常操作导致整个系统的不稳定3.2 攻击合约示例以下是一个利用重入漏洞的攻击合约// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// 攻击合约利用重入漏洞 contract Attacker{VulnerableBank public bank;uint256 public attackCount;/** * notice 构造函数初始化目标银行合约地址 * param _bankAddress 目标银行合约地址 */ constructor(address _bankAddress){bankVulnerableBank(_bankAddress);}/** * notice 发起攻击 * dev 攻击流程先存款再提现在receive中触发重入 */functionattack()public payable{require(msg.value1ether,Need at least 1 ether);attackCount0;// 步骤1先向银行存入1 ether bank.deposit{value: msg.value}();// 步骤2发起第一次提现 // 这会触发receive函数在receive中会再次调用withdraw bank.withdraw();}/** * notice 接收以太币时触发重入攻击 * dev 这是攻击的关键在receive函数中再次调用withdraw */ receive()external payable{// 限制攻击次数避免Gas耗尽if(attackCount3address(bank).balance1ether){attackCount;// 重入攻击再次调用withdraw // 此时bank的balances[address(this)]还没有被清零 bank.withdraw();}}/** * notice 提取攻击获得的资金 */functiongetStolen()public{payable(msg.sender).transfer(address(this).balance);}}攻击流程1. 攻击者调用attack()存入1 ether - bank.balances[attacker]1ether2. 攻击者调用withdraw()- 检查余额1 ether通过 - 向攻击者转账1 ether - 触发攻击者的receive()函数3. receive()函数中再次调用withdraw()- 此时balances[attacker]还是1 ether还没被清零 - 检查余额1 ether通过 - 再次向攻击者转账1 ether - 再次触发receive()函数4. 重复步骤3直到攻击次数达到限制 - 最终攻击者提取了4 ether1 ether本金 3ether窃取3.3 安全方案1Pull Over Push模式Pull Over Push模式的核心思想是让用户主动来提现而不是合约主动推送资金。Pull模式实现// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// Pull模式用户主动提现 contract SafeBankPull{// 记录每个用户的待提现金额 mapping(addressuint256)public pendingWithdrawals;/** * notice 存款函数 * dev 用户存入以太币 */functiondeposit()public payable{// 直接记录待提现金额不立即转账 pendingWithdrawals[msg.sender]msg.value;}/** * notice 提现函数Pull模式 * dev 用户主动调用此函数来提取自己的资金 */functionwithdraw()public{// 获取用户的待提现金额 uint256 amountpendingWithdrawals[msg.sender];require(amount0,No pending withdrawal);// 先清零待提现金额防止重入 pendingWithdrawals[msg.sender]0;// 然后转账(bool success,)msg.sender.call{value: amount}();require(success,Transfer failed);}/** * notice 查询合约余额 */functiongetBalance()public view returns(uint256){returnaddress(this).balance;}}Pull模式的优势防止重入攻击余额在转账前就被清零即使发生重入余额检查也会失败Gas由用户承担用户主动调用withdrawGas消耗由用户支付不会因为Gas耗尽导致功能不可用更好的用户体验用户可以选择何时提现可以分批提现更灵活3.4 安全方案2CEI原则CEI原则Checks-Effects-Interactions是一个非常重要的安全原则。执行顺序是首先进行所有的检查然后更新合约的状态变量最后才进行外部交互。CEI模式实现// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// CEI模式遵循检查-效果-交互原则 contract SafeBankCEI{mapping(addressuint256)public balances;/** * notice 存款函数 */functiondeposit()public payable{balances[msg.sender]msg.value;}/** * notice 提现函数遵循CEI原则 * dev 按照Checks-Effects-Interactions的顺序执行 */functionwithdraw()public{//1. Checks检查验证所有条件 uint256 amountbalances[msg.sender];require(amount0,No balance);//2. Effects效果先更新状态 // 关键在外部调用之前更新状态 // 这样即使发生重入余额检查也会失败 balances[msg.sender]0;//3. Interactions交互然后进行外部调用(bool success,)msg.sender.call{value: amount}();require(success,Transfer failed);}/** * notice 查询合约余额 */functiongetBalance()public view returns(uint256){returnaddress(this).balance;}}CEI原则的关键点Checks检查首先验证所有前置条件检查余额是否足够检查参数是否有效Effects效果然后更新合约状态将余额清零更新其他状态变量Interactions交互最后进行外部调用转账给用户调用外部合约为什么CEI模式安全余额在外部调用前就是0即使发生重入余额检查也会失败require(amount 0)会失败攻击无效3.5 结合重入锁除了CEI原则我们还可以使用重入锁提供额外的保护// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// 结合CEI和重入锁的安全实现 contract SafeBankWithLock{mapping(addressuint256)public balances;// 重入锁 bool private locked;/** * notice 重入锁修饰符 * dev 防止函数被重入调用 */ modifiernoReentrant(){require(!locked,No reentrancy);lockedtrue;_;lockedfalse;}functiondeposit()public payable{balances[msg.sender]msg.value;}/** * notice 提现函数CEI 重入锁 * dev 双重保护CEI原则 重入锁 */functionwithdraw()public noReentrant{// Checks uint256 amountbalances[msg.sender];require(amount0,No balance);// Effects balances[msg.sender]0;// Interactions(bool success,)msg.sender.call{value: amount}();require(success,Transfer failed);}}最佳实践优先使用CEI模式零成本关键函数添加重入锁额外保护使用OpenZeppelin的ReentrancyGuard经过审计4. 状态机模式状态机模式用于管理合约的生命周期。通过定义有限状态和状态转换规则我们可以规范合约的行为确保在正确的状态下执行正确的操作。4.1 什么是状态机状态机State Machine是一种计算模型它定义了一组有限的状态以及状态之间的转换规则。在不同的状态下系统允许执行的操作是不同的。状态机的核心概念状态State系统在某个时刻的特定情况用enum定义所有可能的状态转换Transition从一个状态转换到另一个状态需要满足特定的条件规则Rules定义在什么状态下可以执行什么操作确保操作的合法性状态机模式的优势行为规范每个状态下允许的操作是明确的避免了在错误的时间执行错误的操作可预测性状态转换的逻辑集中管理便于理解和维护安全性防止在错误状态下执行操作减少逻辑错误4.2 ICO众筹示例让我们通过一个ICO众筹的例子来理解状态机模式// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;// 状态机模式ICO众筹合约 contract SimpleCrowdfunding{// 定义所有可能的状态 enum State{Preparing, // 准备阶段项目初始化还未开始募资 Funding, // 募资阶段用户可以投资 Success, // 成功达到募资目标 Failed // 失败未达到募资目标}// 当前状态 State public state;// 项目信息 address public owner;uint256 public goal;// 募资目标 uint256 public raised;// 已募集金额 uint256 public deadline;// 截止时间 // 记录每个用户的投资金额 mapping(addressuint256)public contributions;// 事件记录状态变化和投资 event StateChanged(State newState);event Contributed(address indexed contributor, uint256 amount);/** * notice 构造函数初始化项目 * param _goal 募资目标wei * param _durationMinutes 募资持续时间分钟 * dev 项目初始状态为Preparing */ constructor(uint256 _goal, uint256 _durationMinutes){ownermsg.sender;goal_goal;deadlineblock.timestamp (_durationMinutes *1minutes);stateState.Preparing;// 初始状态准备阶段}/** * notice inState修饰符检查当前状态 * param _state 要求的状态 * dev 确保函数只在特定状态下可以执行 */ modifier inState(State _state){require(state_state,Wrong state);_;}/** * notice onlyOwner修饰符只有所有者可以调用 */ modifieronlyOwner(){require(msg.senderowner,Not owner);_;}/** * notice 开始募资 * dev 只有owner可以调用且只能在Preparing状态下调用 */functionstartFunding()public onlyOwner inState(State.Preparing){// 状态转换Preparing -Funding stateState.Funding;emit StateChanged(State.Funding);}/** * notice 投资函数 * dev 只能在Funding状态下调用且必须在截止时间之前 */functioncontribute()public payable inState(State.Funding){// 检查是否在截止时间之前 require(block.timestampdeadline,Funding ended);require(msg.value0,Must send ETH);// 更新状态 contributions[msg.sender]msg.value;raisedmsg.value;emit Contributed(msg.sender, msg.value);}/** * notice 完成募资 * dev 只能在Funding状态下调用且必须在截止时间之后 * dev 根据募集金额是否达到目标转换到Success或Failed状态 */functionfinalize()public inState(State.Funding){// 检查是否已经过了截止时间 require(block.timestampdeadline,Funding not ended);// 根据募集金额决定最终状态if(raisedgoal){// 达到目标转换到Success状态 stateState.Success;emit StateChanged(State.Success);}else{// 未达到目标转换到Failed状态 stateState.Failed;emit StateChanged(State.Failed);}}/** * notice 提取资金只有成功时才能提取 * dev 只能在Success状态下调用只有owner可以调用 */functionwithdrawFunds()public onlyOwner inState(State.Success){payable(owner).transfer(address(this).balance);}/** * notice 退款失败时用户可以退款 * dev 只能在Failed状态下调用 */functionrefund()public inState(State.Failed){uint256 amountcontributions[msg.sender];require(amount0,No contribution);// 清零投资记录防止重复退款 contributions[msg.sender]0;// 退款给用户 payable(msg.sender).transfer(amount);}}状态流转图Preparing准备阶段 ↓ startFunding()Funding募资阶段 ↓ finalize()├─ raisedgoal → Success成功 └─ raisedgoal → Failed失败状态机模式的关键点使用enum定义状态清晰明确易于扩展使用修饰符检查状态inState修饰符确保函数只在正确状态下执行减少错误操作状态转换逻辑集中所有状态转换都在特定函数中便于维护和审计4.3 适用场景状态机模式非常适合有明确生命周期的场景众筹项目准备、募资、成功/失败拍卖系统创建、竞拍、结束、结算游戏合约准备、进行中、结束投票系统创建、投票中、计票、完成
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

虎牙网页游戏大厅新乡网站seo

前段时间,我一个做自媒体的朋友跟我吐槽,说他花三小时剪好的视频,因为换了个背景音乐,整个音画同步全乱了,相当于白干。说实话,这种崩溃瞬间我太懂了——视频替换音频看似简单,但里面的门道还真…

张小明 2026/1/11 18:04:17 网站建设

单页营销网站设计学软件开发需要学什么

第一章:Open-AutoGLM未成年人隐私保护概述在人工智能快速发展的背景下,Open-AutoGLM作为一款面向公众的生成式语言模型,必须严格遵循数据隐私与安全规范,尤其在涉及未成年人信息处理时需采取额外保护机制。该模型的设计从数据采集…

张小明 2026/1/12 1:29:55 网站建设

淄博网站的建设陕西省建设总工会网站

STM32固件升级实战:从Keil生成Bin到Bootloader无缝跳转一个常见的工程痛点你有没有遇到过这样的场景?产品已经部署在现场,客户反馈有个关键Bug需要修复。你改完代码、编译测试通过,兴冲冲地准备发新版——结果发现,Kei…

张小明 2026/1/11 17:33:50 网站建设

网站购物车作用做印刷的网站

zotero-style插件终极指南:快速掌握文献管理神器 【免费下载链接】zotero-style zotero-style - 一个 Zotero 插件,提供了一系列功能来增强 Zotero 的用户体验,如阅读进度可视化和标签管理,适合研究人员和学者。 项目地址: http…

张小明 2026/1/11 23:48:15 网站建设

网站开发岗位实际情况淘宝网站建设类目需要什么资质

历史文献翻译:古籍英译大模型在TensorRT上高效执行 在数字人文浪潮席卷全球的今天,如何让尘封千年的典籍“活”起来,成为跨文化交流的重要桥梁,已成为学术界与技术界共同关注的焦点。尤其是中华古代文献——从《论语》到《资治通鉴…

张小明 2026/1/12 5:48:03 网站建设

网站开发工程师应聘书范文美团广告投放平台

公益众筹爱心捐赠 目录 基于springboot vue公益众筹爱心捐赠系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue公益众筹爱心捐赠系统 一、前言 博…

张小明 2026/1/11 18:31:29 网站建设