智能合约分享

智能合约练习

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

一、solidity初学者经典示例代码:

1.存储和检索数据:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明 Solidity 编译器版本// 定义一个名为 SimpleStorage 的合约
contract SimpleStorage {// 声明一个公共状态变量 data,用于存储一个 256 位的无符号整数uint256 public data;// 定义一个公共函数 setData,接受一个无符号整数参数 _datafunction setData(uint256 _data) public {// 将传入的参数 _data 存储到状态变量 data 中data = _data;}// 定义一个公共视图函数 getData,返回一个无符号整数function getData() public view returns (uint256) {// 返回当前存储在状态变量 data 中的值return data;}
}

该合约的主要功能是允许用户存储一个无符号整数并检索该整数。通过调用 setData 函数,用户可以更新存储的数据,而通过调用 getData 函数,用户可以查看当前存储的值。这是一个简单的存储合约,常用于学习 Solidity 和以太坊的基本概念

2.条件控制:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明 Solidity 编译器版本// 定义一个名为 ConditionExample 的合约
contract ConditionExample {// 定义一个公共纯函数 checkEven,接受一个无符号整数参数 _numberfunction checkEven(uint256 _number) public pure returns (bool) {// 使用条件语句检查 _number 是否为偶数if (_number % 2 == 0) {// 如果 _number 是偶数,返回 truereturn true;} else {// 如果 _number 不是偶数,返回 falsereturn false;}}
}

该合约提供了一个简单的功能,用于检查一个数字是否为偶数。通过调用 checkEven 函数,用户可以传入一个无符号整数,合约将返回一个布尔值,指示该数字的偶数性。这是一个基本的示例,展示了如何在 Solidity 中使用条件语句和函数。

3.数组操作:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明 Solidity 编译器版本// 定义一个名为 ArrayExample 的合约
contract ArrayExample {// 声明一个公共状态变量 numbers,用于存储一个无符号整数数组uint256[] public numbers;// 定义一个公共函数 addNumber,接受一个无符号整数参数 _numberfunction addNumber(uint256 _number) public {// 将 _number 添加到 numbers 数组中numbers.push(_number);}// 定义一个公共视图函数 getNumber,接受一个无符号整数参数 _indexfunction getNumber(uint256 _index) public view returns (uint256) {// 检查索引 _index 是否有效require(_index < numbers.length, "Invalid index.");// 返回 numbers 数组中索引为 _index 的值return numbers[_index];}// 定义一个公共视图函数 getLength,返回一个无符号整数function getLength() public view returns (uint256) {// 返回 numbers 数组的长度return numbers.length;}
}

该合约展示了如何在 Solidity 中使用数组。用户可以通过 addNumber 函数将数字添加到数组中,使用 getNumber 函数根据索引访问数组元素,使用 getLength 函数获取数组的当前长度。这是一个基本的合约,适合学习 Solidity 中数组的操作。

4.循环遍历:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明 Solidity 编译器版本// 定义一个名为 LoopExample 的合约
contract LoopExample {// 声明一个公共状态变量 numbers,用于存储一个无符号整数数组uint256[] public numbers;// 定义一个公共函数 addNumbers,接受一个无符号整数数组参数 _numbersfunction addNumbers(uint256[] memory _numbers) public {// 使用 for 循环遍历传入的 _numbers 数组for (uint256 i = 0; i < _numbers.length; i++) {// 将 _numbers 中的每个元素添加到 numbers 数组中numbers.push(_numbers[i]);}}// 定义一个公共视图函数 sumNumbers,返回一个无符号整数function sumNumbers() public view returns (uint256) {// 初始化 sum 变量为 0,用于计算总和uint256 sum = 0;// 使用 for 循环遍历 numbers 数组for (uint256 i = 0; i < numbers.length; i++) {// 将 numbers 中的每个元素加到 sum 中sum += numbers[i];}// 返回总和return sum;}
}

该合约通过 addNumbers 函数提供了批量添加数字的功能,通过 sumNumbers 函数提供了计算数组元素总和的功能。合约展示了如何使用数组和循环在 Solidity 中进行简单的数据处理。这些功能适合学习如何在 Solidity 中处理数组操作和循环结构。

二、solidity进阶版经典示例代码

1.智能合约间的通信:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明使用的 Solidity 编译器版本// 定义一个名为 MessageContract 的合约
contract MessageContract {// 声明一个公共状态变量 message,用于存储消息string public message;// 定义一个公共函数 setMessage,接受一个字符串参数 _messagefunction setMessage(string memory _message) public {// 将传入的 _message 赋值给状态变量 messagemessage = _message;}
}// 定义一个名为 CallerContract 的合约
contract CallerContract {// 声明一个公共状态变量 messageContract,类型为 MessageContractMessageContract public messageContract;// 构造函数,接受一个 MessageContract 类型的参数 _messageContractconstructor(MessageContract _messageContract) {// 将传入的合约地址赋值给状态变量 messageContractmessageContract = _messageContract;}// 定义一个公共函数 setMessage,接受一个字符串参数 _messagefunction setMessage(string memory _message) public {// 调用 MessageContract 的 setMessage 函数,设置消息messageContract.setMessage(_message);}
}

MessageContract 合约提供了一个简单的功能,用于存储和更新一条消息。CallerContract 合约则充当一个中介,允许外部用户通过它来设置 MessageContract 中的消息。这种设计展示了如何在 Solidity 中进行合约之间的交互

2.继承和接口:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 指定合约使用的 Solidity 版本// 定义一个名为 Token 的接口
interface Token {// 定义转账函数 transfer,接收目标地址和转账金额function transfer(address _to, uint256 _value) external returns (bool);
}// 定义一个名为 MyToken 的合约,继承自 Token 接口
contract MyToken is Token {// 声明一个公共映射 balances,用于存储每个地址的余额mapping(address => uint256) public balances;// 实现 transfer 函数,覆盖接口中的 transfer 函数function transfer(address _to, uint256 _value) public override returns (bool) {// 检查发送者的余额是否足够require(balances[msg.sender] >= _value, "Insufficient balance.");// 扣除发送者的余额balances[msg.sender] -= _value;// 增加接收者的余额balances[_to] += _value;// 返回成功标志return true;}
}

Token 接口定义了一个代币转账的基本功能。MyToken 合约实现了该接口,并提供了代币转账的具体逻辑。此合约的设计体现了 Solidity 中接口和合约之间的关系,以及如何通过状态变量管理每个地址的余额。

3.事件和日志:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 指定合约使用的 Solidity 版本// 定义合约 EventExample
contract EventExample {// 定义事件 LogAddition,带有 sender 地址和两个输入参数及其结果event LogAddition(address indexed _sender, uint256 _a, uint256 _b, uint256 _result);// 定义一个公共函数 addNumbers,接收两个无符号整数作为参数function addNumbers(uint256 _a, uint256 _b) public returns (uint256) {// 计算两个数的和uint256 result = _a + _b;// 触发 LogAddition 事件,记录发送者地址、输入参数和结果emit LogAddition(msg.sender, _a, _b, result);// 返回计算结果return result;}
}

该合约提供了一个简单的加法功能,并通过事件记录了每次加法操作的详细信息,包括发送者的地址和加法的输入输出。事件在以太坊智能合约中用于记录和追踪操作,这些信息在区块链上是不可变的,便于后续查询和审计。

三、solidity高阶版经典示例代码

1.多重签名钱包合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 指定 Solidity 版本contract MultiSigWallet {address[] public owners; // 钱包所有者数组uint public numConfirmationsRequired; // 执行交易所需的确认数量struct Transaction {address to; // 接收资金的地址uint value; // 发送的金额bool executed; // 交易是否已执行mapping(address => bool) isConfirmed; // 所有者的确认状态映射uint numConfirmations; // 收到的确认数量}Transaction[] public transactions; // 交易数组modifier onlyOwner() {require(isOwner(msg.sender), "Only owners can call this function.");_; // 继续执行}constructor(address[] memory _owners, uint _numConfirmationsRequired) {require(_owners.length > 0, "At least one owner is required.");require(_numConfirmationsRequired > 0 && _numConfirmationsRequired <= _owners.length, "Invalid number of required confirmations.");owners = _owners; // 设置所有者numConfirmationsRequired = _numConfirmationsRequired; // 设置所需确认数量}function isOwner(address _address) public view returns (bool) {for (uint i = 0; i < owners.length; i++) {if (owners[i] == _address) {return true; // 地址是所有者}}return false; // 地址不是所有者}function submitTransaction(address _to, uint _value) public onlyOwner {uint transactionId = transactions.length; // 获取当前交易 IDtransactions.push(Transaction({to: _to,value: _value,executed: false,numConfirmations: 0}));confirmTransaction(transactionId); // 自动确认提交的交易}function confirmTransaction(uint _transactionId) public onlyOwner {require(_transactionId < transactions.length, "Invalid transaction ID.");require(!transactions[_transactionId].executed, "Transaction has already been executed.");require(!transactions[_transactionId].isConfirmed[msg.sender], "Transaction has already been confirmed by this owner.");transactions[_transactionId].isConfirmed[msg.sender] = true; // 标记为发送者已确认transactions[_transactionId].numConfirmations++; // 增加确认计数// 如果满足所需确认数量,则执行交易if (transactions[_transactionId].numConfirmations >= numConfirmationsRequired) {executeTransaction(_transactionId);}}function executeTransaction(uint _transactionId) public onlyOwner {require(_transactionId < transactions.length, "Invalid transaction ID.");require(!transactions[_transactionId].executed, "Transaction has already been executed.");Transaction storage transaction = transactions[_transactionId];transaction.executed = true; // 标记交易为已执行(bool success, ) = transaction.to.call{value: transaction.value}(""); // 执行交易require(success, "Transaction execution failed."); // 确保交易成功}
}

这个多重签名钱包合约提供了一种稳健的资金管理机制,要求多个所有者批准交易才能执行。可以通过增加撤销确认或添加/删除所有者等功能进一步增强安全性和灵活性。

2.众筹合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 指定使用的 Solidity 版本contract Crowdfunding {struct Project {address owner; // 项目拥有者的地址string name; // 项目名称uint goalAmount; // 项目的筹款目标uint amountRaised; // 已筹集的总金额bool closed; // 指示项目是否关闭接受捐款mapping(address => uint) contributions; // 每个地址的捐款记录}Project[] public projects; // 存储所有项目的数组// 创建新众筹项目的函数function createProject(string memory _name, uint _goalAmount) public {projects.push(Project({owner: msg.sender, // 将调用函数的地址设置为项目拥有者name: _name, // 项目名称goalAmount: _goalAmount, // 筹款目标amountRaised: 0, // 初始筹集金额为零closed: false // 项目默认开放接受捐款}));}// 向项目捐款的函数function contribute(uint _projectId) public payable {require(_projectId < projects.length, "Invalid project ID."); // 确保项目存在require(msg.value > 0, "Contribution amount must be greater than zero."); // 确保捐款金额大于零require(!projects[_projectId].closed, "Project is closed for contributions."); // 确保项目未关闭projects[_projectId].contributions[msg.sender] += msg.value; // 记录捐款projects[_projectId].amountRaised += msg.value; // 更新已筹集的总金额}// 关闭项目的函数function closeProject(uint _projectId) public {require(_projectId < projects.length, "Invalid project ID."); // 确保项目存在require(msg.sender == projects[_projectId].owner, "Only project owner can close the project."); // 只有拥有者才能关闭项目projects[_projectId].closed = true; // 将项目标记为已关闭}// 提取项目资金的函数function withdrawFunds(uint _projectId) public {require(_projectId < projects.length, "Invalid project ID."); // 确保项目存在require(msg.sender == projects[_projectId].owner, "Only project owner can withdraw funds."); // 只有拥有者才能提取资金require(projects[_projectId].amountRaised >= projects[_projectId].goalAmount, "Goal amount has not been reached yet."); // 确保已达成筹款目标uint amountToWithdraw = projects[_projectId].amountRaised; // 要提取的金额projects[_projectId].amountRaised = 0; // 将已筹集金额重置为零payable(msg.sender).transfer(amountToWithdraw); // 将资金转移给拥有者}
}

所提供的众筹合约作为一个基本框架,用于在以太坊区块链上管理众筹项目。通过上述改进和考虑,可以增强合约的安全性、可用性和功能性

希望该篇文章可以帮助到正在学习solidity的朋友哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/461537.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

硬件在环仿真建模之电路拓扑建模与数学建模

我们需要先明确一个问题&#xff0c;什么是电路拓扑式建模&#xff08;后面简称拓扑建模&#xff09;和数学建模&#xff1f; 电力电子系统的拓扑建模&#xff0c;从大类上都可以归入为物理式建模&#xff08;Physics-Based Modeling&#xff09;,物理式建模的最大特点就是用户…

根据提交的二维数据得到mysql建表和插入数据实用工具

根据提交的二维数据得到mysql建表和插入数据实用工具,这是重构版本(之前有过)。 会通过数据的长度&#xff0c;类型&#xff0c;是否数字&#xff0c;是否唯一等做判断&#xff0c;且每千条一个插入语句以优化性能。 <?php //整理与分享&#xff1a;yujianyue<1505859…

从0开始electron+vue2搭建环境

使用环境&#xff1a;node版本16.16.0 目录 搭建vue项目安装electron打包electron 搭建vue项目 已有vue2的环境直接进项安装electron步骤 没有的请先移动到这里查看 vue2脚手架搭建项目流程 我就不另外记录了 安装electron 直接运行 vue add electron-builder安装完成后&…

Qt——QWidget

一.控件概述 Widget 是 Qt 中的核心概念. 英文原义是 "小部件"&#xff0c;我们也把它翻译为 "控件" 。 控件是构成⼀个图形化界面的基本要素。 像上述示例中的, 按钮, 列表视图, 树形视图, 单行输入框, 多行输入框, 滚动条, 下拉框等, 都可以称为 "…

最经典盲超分辨率数据集

一、背景 底层视觉的发展是否能够让我们真正地看清这个世界呢&#xff1f; 在单图超分中&#xff0c;非盲超分已经发展得较为成熟了&#xff0c;而盲超分和真实超分仍然有很多问题尚未解决。在我看来&#xff0c;盲超分只是真实超分的一个过渡&#xff0c;由于真实世界中退化…

Spring Boot 配置文件详解与最佳实践

目录 前言1. 配置文件的作用2. Spring Boot 主要配置内容2.1 Actuator 配置2.2 缓存配置2.3 核心配置2.4 数据库与数据迁移配置2.5 开发工具配置2.6 Docker Compose 配置2.7 JSON 配置2.8 安全配置 3. 多个配置文件的处理方法3.1 使用 Profile 文件区分环境3.2 结合优先级加载配…

【Stable Diffusion】

1、SD 模型 安装完SD软件后&#xff0c;必须搭配基础模型才能使用。 不同的基础模型&#xff0c;其画风和擅长的领域会有侧重。 Checkpoint大模型 大模型是 SD 的核心&#xff0c;用来控制生成图片的整个画面风格走势。 出图前要选择好合适的大模型&#xff0c;比如有些擅长…

吉林大学2023级数据结构上机实验第(1~2周)参考答案(关注我,在系统关闭后持续更新)

A 括号匹配&#xff08;进阶版&#xff09; 分数 10 编写程序检查给定字符串中包含的括号是否正确匹配&#xff0c;本题中的括号有{ }、[ ]、( )、< >四种。另外再加上一个新的约束条件&#xff1a;当有多种括号嵌套时&#xff0c;嵌套的顺序应为{ → [ → ( → <&…

【综合算法学习】(第十三篇)

目录 解数独&#xff08;hard&#xff09; 题目解析 讲解算法原理 编写代码 单词搜索&#xff08;medium&#xff09; 题目解析 解析算法原理 编写代码 解数独&#xff08;hard&#xff09; 题目解析 1.题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;…

【C++】string 类模拟实现:深入探索字符串操作原理

快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f6a9;在之前的文章中我们学会了对string类函数的使用&#xff0c;现在让我们对其进行模拟实现吧~&#x1f6a9; 目录 &#x1f4af;引言 &#x1f4…

[c++高阶]AVL树的深度剖析模拟实现

1.前言 如果你不知道什么是二叉搜索树&#xff0c;那么请你一定要阅读以下文章。 [c高阶]二叉搜索树深度剖析-CSDN博客 二叉搜索树如果在已经有序的情况下进行插入的话&#xff0c;那么他的时间复杂度是O(N)&#xff0c;然后有时候的时间复杂度又是O(logN)&#xff0c;因此在实…

我在命令行下剪辑视频

是的&#xff0c;你不需要格式工厂&#xff0c;你也不需要会声会影&#xff0c;更不需要爱剪辑这些莫名其妙的流氓软件&#xff0c;命令行下视频处理&#xff0c;包括剪辑&#xff0c;转码&#xff0c;提取&#xff0c;合成&#xff0c;缩放&#xff0c;字幕&#xff0c;特效等…

Tita:什么是 360 评估?

360 评估是一个专业的反馈机会&#xff0c;使一组同事和经理能够提供有关同事绩效的反馈。与仅由其经理评估员工工作绩效的典型员工绩效评估不同&#xff0c;360 评估会考虑来自同事和报告员工的反馈&#xff0c;甚至包括客户和与员工互动的其他人。 Tita&#xff1a;什么是 3…

jenkins ssh 免密报错Host key verification failed.

jenkins 发布项目&#xff0c;ssh连接远程服务器时报错&#xff1a;Host key verification failed. 解决&#xff1a; 原因是生成的sshkey不是用的jenkins用户&#xff0c;所以切换用户到&#xff1a;jenkins重新生成sshkey su jenkins ssh-keygen -t rsa ssh-copy-id -i ~/…

【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库

目录 引入内存级文件重新使用C文件接口 -- 对比重定向写文件读文件文件流 认识文件操作的系统接口open参数 -- flagflag的内容宏的传参方式 open关闭文件写文件读文件结论 引入文件描述符fd、对文件的理解理解一切皆文件方法集文件fd的分配规则 重定向代码的重定向输入重定向输…

创意设计的起点:十大网页设计模板网站

对于网页设计领域的专业人士和爱好者而言&#xff0c;从零开始构建一个网页可能会耗费大量的时间和劳力。幸运的是&#xff0c;我们可以通过使用现成的网页模板来提升工作效率并节省宝贵的时间。一个好的模板不仅能提高设计效率&#xff0c;还能激发出卓越的创意灵感。因此&…

鸿蒙Harmony-矩形绘制组件Rect使用详解

目录 一&#xff0c;定义 二&#xff0c;绘制自定义图形 三&#xff0c;作为其他控件背景使用 一&#xff0c;定义 Rect是鸿蒙提供的矩形绘制组件&#xff0c;利用该组件可以绘制矩形背景&#xff0c;矩形图案等 官方提供的参数和属性&#xff1a; 参数&#xff1a; 参数名…

netty之bootstrap源码分析

写在前面 本文看下bootstrap类。 1&#xff1a;正文 1.1&#xff1a;干啥的&#xff1f; 在进行netty编程的时候都是先创建一个bootstrap&#xff0c;然后设置很多的东西&#xff0c;如下代码&#xff08;服务端启动代码&#xff09;&#xff1a; ServerBootstrap b new …

c# WinForm弹出窗体时不获取焦点方法

WinForm开发的软件有时候需要在屏幕右下角弹窗进行一些提示&#xff0c;通常使用new MyForm().Show()即可实现此需求。 但是当MyForm显示出来时&#xff0c;会抢走原本窗体上的光标&#xff0c;导致原本在软件上比如打字或者其他操作被中断&#xff0c;非常不人性化&#xff0…

方差和标准差哪些事儿

1.方差 在概率论与数理统计中&#xff0c;方差用来度量随机变量和其数学期望&#xff08;即均值&#xff09;之间的偏离程度。方差是各个数据与平均数之差的平方和的平均数,即: s(1/n)[(x1-x_)^2 (x2-x_)^2 …(xn-x_)^2] 其中&#xff0c;x_表示样本的平均数&#xff0c;n表示…