智能合约分享

智能合约练习

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

在这里插入图片描述

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

1.存储和检索数据:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明 Solidity 编译器版本

// 定义一个名为 SimpleStorage 的合约
contract SimpleStorage {
    // 声明一个公共状态变量 data,用于存储一个 256 位的无符号整数
    uint256 public data;

    // 定义一个公共函数 setData,接受一个无符号整数参数 _data
    function 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,接受一个无符号整数参数 _number
    function checkEven(uint256 _number) public pure returns (bool) {
        // 使用条件语句检查 _number 是否为偶数
        if (_number % 2 == 0) {
            // 如果 _number 是偶数,返回 true
            return true;
        } else {
            // 如果 _number 不是偶数,返回 false
            return false;
        }
    }
}

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

3.数组操作:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // 声明 Solidity 编译器版本

// 定义一个名为 ArrayExample 的合约
contract ArrayExample {
    
    // 声明一个公共状态变量 numbers,用于存储一个无符号整数数组
    uint256[] public numbers;

    // 定义一个公共函数 addNumber,接受一个无符号整数参数 _number
    function addNumber(uint256 _number) public {
        // 将 _number 添加到 numbers 数组中
        numbers.push(_number);
    }

    // 定义一个公共视图函数 getNumber,接受一个无符号整数参数 _index
    function 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,接受一个无符号整数数组参数 _numbers
    function 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,接受一个字符串参数 _message
    function setMessage(string memory _message) public {
        // 将传入的 _message 赋值给状态变量 message
        message = _message;
    }
}

// 定义一个名为 CallerContract 的合约
contract CallerContract {
    // 声明一个公共状态变量 messageContract,类型为 MessageContract
    MessageContract public messageContract;

    // 构造函数,接受一个 MessageContract 类型的参数 _messageContract
    constructor(MessageContract _messageContract) {
        // 将传入的合约地址赋值给状态变量 messageContract
        messageContract = _messageContract;
    }

    // 定义一个公共函数 setMessage,接受一个字符串参数 _message
    function 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; // 获取当前交易 ID
        transactions.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的朋友哦。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Couldn‘t apply path mapping to the remote file.

Couldn’t apply path mapping to the remote file. /s6home2/zjw524/projects/seq2seq/code/deepnmtpycharm/deepNmt/code/deepNmtPycharm/deepNmt/model/Deep_NMT_Model.py can’t be found in project. You can continue debugging, but without the source. To fix that yo…

4.2-6 使用Hadoop WebUI

文章目录 1. 查看HDFS集群状态1.1 端口号说明1.2 用主机名访问1.3 主节点状态1.4 用IP地址访问1.5 查看数据节点 2. 操作HDFS文件系统2.1 查看HDFS文件系统2.2 在HDFS上创建目录2.3 上传文件到HDFS2.4 删除HDFS文件和目录 3. 查看YARN集群状态4. 实战总结 1. 查看HDFS集群状态 …

嵌入式硬件电子电路设计(一)开关电源Buck电路

目录 Buck电路基本结构 1. 开关闭合&#xff08;SW 闭合&#xff09; 2. 开关断开&#xff08;SW 断开&#xff09; 3. 开关控制和占空比 MP1584电路分析 其他Buck芯片的电路参考 Buck电路基本结构 下图是简化之后的BUCK电路主回路。下面分析输出电压的产生K闭合后&…

医院信息化与智能化系统(14)

医院信息化与智能化系统(14) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…

Unity 使用Netcode实现用户登录和登出

Unity之NetCode for GameObjets 基本使用 说明思路相关API代码实现Tips 说明 最近项目需要联机&#xff0c;项目方案选用Unity提供的NetCode for GameObjets&#xff08;以下简称NGO&#xff09;&#xff0c;踩了不少坑&#xff0c;本文不介绍基础使用&#xff0c;围绕双端&am…

【单机游戏】红色警戒游戏介绍和玩法

平地一声惊雷&#xff0c;金将军居然发射了洲际导弹&#xff0c;虽然我们不能亲自体验&#xff0c;但是我们可以自己在游戏中体验一把&#xff0c;今天就介绍一个很多80 90都玩过的即时战略游戏-红色警戒 https://pan.quark.cn/s/7aca45fa3dd7 红色警戒&#xff08;Red Alert …

【Python各个击破】matplotlib

导入 import matplotlib.pyplot as plt import numpy as np用法 # 根据x,y数组作图 fig, ax plt.subplots() ax.plot([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,…

JavaEE初阶---网络原理之TCP篇(二)

文章目录 1.断开连接--四次挥手1.1 TCP状态1.2四次挥手的过程1.3time_wait等待1.4三次四次的总结 2.前段时间总结3.滑动窗口---传输效率机制3.1原理分析3.2丢包的处理3.3快速重传 4.流量控制---接收方安全机制4.1流量控制思路4.2剩余空间大小4.3探测包的机制 5.拥塞控制---考虑…

ssm022房屋租售网站的设计与实现+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;房屋租售网站的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为…

Knife4j配置 ▎使用 ▎教程 ▎实例

knife4j简介 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试.参数和格式都…

CSS flex布局- 最后一个元素占满剩余可用高度转载

效果图 技术要点 height父元素必须有一个设定的高度flex-grow: 1 flex 盒子模型内的该元素将会占据父容器中剩余的空间F12检查最后一行的元素&#xff0c;高度就已经改变了&#xff1b;

虚拟环境设置成kernel来解决一些jupyter报错问题

1. 下面提到的问题应该是不同环境&#xff08;base、虚拟环境&#xff09;的区别&#xff0c;而不是python版本的区别。 2. 这个方法起到了比较好的效果&#xff0c;但是底层的逻辑还没太明白&#xff0c;有时间继续研究下。 3. 最终的结果好像是pycharm、anaconda用的python…

(五)Web前端开发进阶2——AJAX

目录 1.Ajax概述 2.Axios库 3.认识URL 4.Axios常用请求方法 5.HTTP协议——请求报文/响应报文 6.前后端分离开发 7.Element组件库 1.Ajax概述 AJAX 是异步的 JavaScript和XML(Asynchronous JavaScript And XML)。简单点说&#xff0c;就是使用XMLHttpRequest 对象与服务…

揭秘PyInstaller:Python应用打包的瑞士军刀

文章目录 **揭秘PyInstaller&#xff1a;Python应用打包的瑞士军刀**1. 背景介绍&#xff1a;为何选择PyInstaller&#xff1f;2. PyInstaller究竟是什么&#xff1f;3. 如何安装PyInstaller&#xff1f;4. PyInstaller的简单使用方法4.1 打包单个Python脚本4.2 生成单个可执行…

Spring Boot 创建项目详细介绍

上篇文章简单介绍了 Spring Boot&#xff08;Spring Boot 详细简介&#xff01;&#xff09;&#xff0c;还没看到的读者&#xff0c;建议看看。 下面&#xff0c;介绍一下如何创建一个 Spring Boot 项目&#xff0c;以及自动生成的目录文件作用。 Maven 构建项目 访问 http…

机器学习——解释性AI(Explainable AI)

机器学习——解释性AI&#xff08;Explainable AI&#xff09; 解释性AI&#xff08;Explainable AI&#xff09;——让机器学习模型更加透明与可信什么是解释性AI&#xff1f;解释性AI的常见方法示例代码&#xff1a;使用SHAP解释随机森林模型示例代码&#xff1a;使用LIME解释…

开源一款基于 JAVA 的仓库管理系统,支持三方物流和厂内物流,包含 PDA 和 WEB 端的源码

大家好&#xff0c;我是一颗甜苞谷&#xff0c;今天分享一款基于 JAVA 的仓库管理系统,支持三方物流和厂内物流,包含 PDA 和 WEB 端的源码。 前言 在当前的物流仓储行业&#xff0c;企业面临着信息化升级的迫切需求&#xff0c;但往往受限于高昂的软件采购和维护成本。现有的…

Tomcat servlet response关于中文乱码的经验

前言 最近修改老项目项目&#xff0c;使用zuul网关返回的中文内容乱码了&#xff0c;如果使用GBK或者GB2312编码确正常显示&#xff0c;稍微实验了一下&#xff0c;发现里面很多细节&#xff0c;毕竟Springboot对我们做了很多事情&#xff0c;而且当我们使用不同的模式会出现很…

【原创分享】详述中间件的前世今生

中间件是一种软件组件&#xff0c;位于应用程序和操作系统之间&#xff0c;通过提供统一的接口和功能来简化开发和管理应用程序、提高应用程序的可靠性和性能。 中间件的前世可以追溯到20世纪80年代的分布式系统和网络技术的发展。在那个时候&#xff0c;随着计算机网络的普及…

JAVA力扣每日一题:P198. 打家劫舍

本题来自&#xff1a;力扣-每日一题 力扣 (LeetCode) 全球极客挚爱的技术成长平台https://leetcode.cn/ 题解&#xff1a; class Solution {public int rob(int[] nums) {int len nums.length;if(len 0)return 0;if(len 1)return nums[0];int first nums[0];int second …