智能合约分享

news2024/10/28 3:06:12

智能合约练习

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

在这里插入图片描述

一、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的朋友哦。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络:数据链路层 —— 虚拟局域网 VLAN

文章目录 局域网虚拟局域网 VLAN虚拟局域网 VLAN 概述实现机制IEEE 802.1Q帧以太网交换机的接口类型Access 接口Trunk 接口Hybrid 接口不进行人为的VLAN划分划分两个不同VLANTrunk接口去标签后进行转发Trunk接口直接转发 局域网 局域网&#xff08;Local Area Network&#xf…

工地安全新突破:AI视频监控提升巡检与防护水平

在建筑工地和其他劳动密集型行业&#xff0c;工人的安全一直是管理工作的重中之重。为了确保工地的安全管理更加高效和智能化&#xff0c;AI视频监控卫士。通过人工智能技术&#xff0c;系统不仅能实时监控&#xff0c;还能自动识别工地现场的安全隐患&#xff0c;为工地管理者…

HeterGCL 论文写作分析

HeterGCL 论文写作分析 这篇文章&#xff0c;由于理论证明较少&#xff0c;因此写作风格了polygcl是两种风格的。polygcl偏向理论的写作风格&#xff0c;而hetergcl就是实践派的风格 首先看标题&#xff0c;其的重点是Graph contrastive learning Framework。其重点是framewo…

标准日志插件项目【C/C++】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;项目日记_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;项目介…

HTML+CSS实现超酷超炫的3D立方体相册

效果演示 HTML和CSS实现一个简单的3D立方体加载动画的相册。它使用了HTML来构建立方体的结构&#xff0c;并通过CSS来添加样式和动画效果。 HTML <div class"loader3d"><div class"cube"><div class"face"><img src&qu…

LabVIEW偏振调制激光高精度测距系统

在航空航天、汽车制造、桥梁建筑等先进制造领域&#xff0c;许多大型零件的装配精度要求越来越高&#xff0c;传统的测距方法在面对大尺寸、高精度测量时&#xff0c;难以满足工业应用的要求。绝对测距技术在大尺度测量上往往会因受环境影响大、测距精度低而无法满足需求。基于…

社交媒体视频素材平台推荐

在内容创作日益重要的今天&#xff0c;社交媒体视频素材的需求不断增加。适合各种平台的视频素材不仅可以提升内容质量&#xff0c;还能吸引更多观众。以下是一些推荐的社交媒体视频素材平台&#xff0c;帮助你找到适合的资源。 蛙学网 蛙学网 是一个专注于社交媒体视频素材的平…

Sora高端制造业WordPress外贸主题

Sora是一款专为高端制造业设计的WordPress主题&#xff0c;由国内知名wordpress开发团队简站wordpress主题开发&#xff0c;它以红色为主色调&#xff0c;适合外贸企业出海建独立站的模板。这个主题适用于WordPress 6.0及以上版本&#xff0c;并且只服务于真正有需要的用户。主…

C++ | Leetcode C++题解之第504题七进制数

题目&#xff1a; 题解&#xff1a; class Solution { public:string convertToBase7(int num) {if (num 0) {return "0";}bool negative num < 0;num abs(num);string digits;while (num > 0) {digits.push_back(num % 7 0);num / 7;}if (negative) {dig…

论文阅读(二十六):Dual Attention Network for Scene Segmentation

文章目录 1.Introduction3.DANet3.1Position Attention Module3.2Channel Attention Module 论文&#xff1a;Dual Attention Network for Scene Segmentation   论文链接&#xff1a;Dual Attention Network for Scene Segmentation   代码链接&#xff1a;Github 1.Intr…

Vue3 学习笔记(五)Vue3 模板语法详解

在 Vue3 的世界里&#xff0c;模板语法是我们构建用户界面的基石。今天&#xff0c;让我们一起深入了解 Vue3 的模板语法&#xff0c;我将用通俗易懂的语言和实用的例子&#xff0c;带你掌握这项必备技能。 1、文本插值&#xff1a;最基础的开始 想在页面上显示数据&#xff1f…

深度学习模型入门教程:从基础到应用

深度学习模型入门教程&#xff1a;从基础到应用 前言 在人工智能的浪潮中&#xff0c;深度学习作为一种强大的技术&#xff0c;正在各行各业中发挥着越来越重要的作用。从图像识别到自然语言处理&#xff0c;深度学习正在改变我们的生活和工作方式。本文将带您深入了解深度学…

OpenCV视觉分析之运动分析(3)背景减除类:BackgroundSubtractorKNN的一系列get函数的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 BackgroundSubtractorKNN类有一系列的get函数&#xff0c;下面我们一一列举他们的名字和用法。 一系列函数 函数getDetectShadows() getDetec…

CSS伪元素以及伪类和CSS特性

伪元素&#xff1a;可以理解为假标签。 有2个伪元素 &#xff08;1&#xff09;::before &#xff08;2&#xff09;::after ::before <!DOCTYPE html> <html> <head><title></title><style type"text/css">body::before{con…

使用Python Pillow库生成九宫格图片

相信很多人看到过九宫格图片&#xff0c;一张完整的大图被分割成九张小图&#xff0c;在朋友圈和微博里一度成为流行。 相比完整的大图&#xff0c;九宫格图文增添了一丝趣味和精致&#xff0c;也显得更有创意。 制作九宫格图片的工具有很多&#xff0c;下文用Python的PIL库来…

Puppeteer 与浏览器版本兼容性:自动化测试的最佳实践

Puppeteer 支持的浏览器版本映射&#xff1a;从 v20.0.0 到 v23.6.0 自 Puppeteer v20.0.0 起&#xff0c;这个强大的自动化库开始支持与 Chrome 浏览器的无头模式和有头模式共享相同代码路径&#xff0c;为自动化测试带来了更多便利。从 v23.0.0 开始&#xff0c;Puppeteer 进…

vue3完整Demo(数据绑定,数据显示,数据修改,数据提交)

需要引入的的依赖&#xff1a;jquery&#xff08;用于异步请求&#xff09; 一、数据显示的前端页面 条件查询数据并显示&#xff0c;下拉框使用的model双向绑定 二、js代码&#xff08;list页面的数据请求&#xff09; 后端传来的时间数据需要转换可以使用new Intl.DateTim…

【NOIP提高组】加分二叉树

【NOIP提高组】加分二叉树 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 设一个n个节点的二叉树tree的中序遍历为&#xff08;l,2,3,…,n&#xff09;&#xff0c;其中数字1,2,3,…,n为节点编号。每个节点都有一个分数&#xff08;均为正整…

【Java并发编程】信号量Semaphore详解

一、简介 Semaphore&#xff08;信号量&#xff09;&#xff1a;是用来控制同时访问特定资源的线程数量&#xff0c;它通过协调各个线程&#xff0c;以保证合理的使用公共资源。 Semaphore 一般用于流量的控制&#xff0c;特别是公共资源有限的应用场景。例如数据库的连接&am…

redis详细教程(2.List教程)

List是一种可以存储多个有序字符串的数据类型&#xff0c;其中的元素按照顺序排列&#xff08;可以重复出现&#xff09;&#xff0c;可以通过数字索引来访问列表中的元素&#xff0c;索引可以从左到右或者从右到左。 Redis 列表可以通过两种方式实现&#xff1a;压缩列表&…