草庐IT

智能合约简单介绍

外咸瓜街的一条咸鱼 2023-09-26 原文

本学期学习了区块链的课程,作业是对于智能合约学习后的报告:

 

1 智能合约简单了解

1.1智能合约是什么

智能合约是由事件驱动的、具有状态的、部署于可共享的分布式数据库上的计算机程序,多用IF-THEN语句。狭义来说,智能合约是设计相关商业逻辑和算法的程序代码,把人、法律和网络的复杂关系代码化;广义来说,智能合约是一种可以实现自我执行和自我验证的计算机协议。乍一看,与数据库中的触发器颇为相似。

简言之,智能合约是一种用计算机语言取代法律语言去记录条款的合约。智能合约可以由一个计算系统自动执行,它可以算是传统合约的数字化版本。

如果把区块链比作一个数据库的话,智能合约就是能够使区块链技术应用到现实生活的应用层。智能合约是在区块链数据库上运行的计算机程序,可以在满足其源代码中写入的条件时自动执行。智能合约编写完毕就可以被用户信赖,合约条款不能更改,因此合约也是不可更改的。

1.2智能合约的技术特点

1.2.1数据透明化

区块链上所有的数据都是公开透明的,因此智能合约的数据处理也是公开透明的,运行时任何一方都可以查看其代码和数据。

1.2.2不可篡改

区块链本身的所有数据不可篡改,因此部署在区块链上的智能合约代码以及运行产生的数据输出也是不可篡改的,运行智能合约的节点不必担心其他节点恶意修改代码与数据。

1.2.3永久运行

支撑区块链网络的节点往往达到数百甚至上千,部分节点的失效并不会导致智能合约的停止,其可靠性理论上接近于永久运行,这样就保证了智能合约能像纸质合同一样每时每刻都有效。

 

2 Solidity语言初步学习

2.1 IDE的使用

在学习过程中使用了在线IDE在本机上该ide截图如下左侧即为文件的列表中间的区域可以快捷新建文件

 

2.第一个智能合约helloworld

2.2.创建项目

新建一个名为Helloworld.sol的文件源码如下相关函数的作用写在了注释里

pragma solidity ^0.4;//版本指令为0.4
contract HelloWorld {//合约创建
function sayHelloWorld() public returns(string){//定义函数,public意味着任何一方 (或其它合约) 都可以调用你合约里的函数。
return ("hello world");
}
}

2.2.2编译运行

在compile选项卡中进行编译,可以点击compilation Details来对编译的具体细节进行了解。这边没有报错,且出现绿色钩子图形表示编译成功。

 在编译成功后,我们就能在run 选项卡中部署该合约

 点击deploy就是部署这个合约,下面就会出现这个合约的函数,点击运行这个合约的函数,日志会输出相应的记录,可见返回了helloworld。

 

 

2.第二个智能合约

对一个简单银行模型的合约进行了学习和编译,对于该模型的理解均以注释的形式写在代码中,通过该合约可以实现存钱,取钱,查看余额的功能:

2.3.1 初始化部分

这边创建了一个银行的简单模型,声明了一个mapping变量来表示余额,进行了一些值和变量的初始化。

2.3.2构造方法

  

2.3.3存钱的方法

2.3.4取钱的方法

2.3.5查看余额的方法

2.3.6对合约进行运行

同helloworld合约一样,编译成功后点击deploy,这边出现了四个方法可以进行选择。

 

我们点击balance和owner分别实现了显示了用户信息和余额的功能,deposit函数也能成功运行,但是withdraw方法却进行了报错,因为这个账户的余额是0,在代码中我们用require函数进行了限制。如果取钱额大于账户余额就会报错,不能实现取款,所以报错。

2.3.7其他

因为这里实现了货币交易,所以会出现收取手续费的提示。gas就是虚拟货币里的手续费的概念,gas越多,交易会越快。

 

 2.3.8 源代码:

pragma solidity 0.6.6;

contract SimpleBank { //创建一个简单银行模型的合约
    
    mapping (address => uint) private balances;//声明了一个mapping类型的变量balance表示余额,这是一个key-value类型,key是address类型,value是uint类型。
//owner用来表示合约持有者的地址。
    address public owner;//address是一种比较特殊的类型,它有20个字节长度,一般用来表示地址或者账户的公钥信息。需要注意的是,虽然看起来它是一个数字的类型,但是它不支持任何的算术运算操作。

    event LogDepositMade(address accountAddress, uint amount);//事件 是合约和区块链通讯的一种机制。你的前端应用“监听”某些事件,并做出反应,通过emit触发事件的执行。

    constructor() public {//构造方法
        owner = msg.sender;//把owner变量赋值为msg.sender,后者是一个约定的内部变量,表示的是方法的调用者。在这里指合约的创建人。
    }


    function deposit() public payable returns (uint) {//deposit表示存钱的方法。被payable关键字修饰的方法可以在调用的时候接收ETH(以太币)。
                                                      //这个方法的首先检查发送的ETH值要必须大于0,然后更新余额,出发日志事件,最后返回余额。
        require((balances[msg.sender] + msg.value) >= balances[msg.sender]);//require使得函数在执行过程中,当不满足某些条件时抛出错误,并停止执行。这边通过该函数判定存入的钱大于0.

        balances[msg.sender] += msg.value;//余额增加

        emit LogDepositMade(msg.sender, msg.value); // 对应上方的event,触发该监听

        return balances[msg.sender];//更新余额
    }


    function withdraw(uint withdrawAmount) public returns (uint remainingBal) {//表示取钱的方法。
        require(withdrawAmount <= balances[msg.sender]);//判定取出的钱小于账户余额。

        
        balances[msg.sender] -= withdrawAmount;//取钱

        msg.sender.transfer(withdrawAmount);//转账一定数量(以wei为单位)的以太币到指定的地址,该地址为调用该函数的人的地址

        return balances[msg.sender];
    }

    function balance() view public returns (uint) {//返回余额的方法。view表示是一个只读的方法,不消耗gas费。
        return balances[msg.sender];
    }
}

有关智能合约简单介绍的更多相关文章

  1. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  2. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  3. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  4. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  5. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  6. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  7. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  8. ruby - 使用 Ruby,计算 n x m 数组的每一列中有多少个 true 的简单方法是什么? - 2

    给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in

  9. ruby - 在 Ruby 中搜索大文件的更简单方法? - 2

    我正在编写一个简单的日志嗅探器,它将在日志中搜索表明我支持的软件存在问题的特定错误。它允许用户指定日志路径并指定他们想要搜索多少天前。如果用户关闭日志滚动,日志文件有时会变得非常大。目前我正在做以下事情(虽然还没有完成):File.open(@log_file,"r")do|file_handle|file_handle.eachdo|line|ifline.match(/\d+++-\d+-\d+/)etc...line.match显然会查找我们在日志中使用的日期格式,其余逻辑将在下面。但是,有没有更好的方法来搜索没有.each_line的文件?如果没有,我完全同意。我只是想确保我使

  10. ruby - 如何排序不是简单的哈希(哈希的哈希) - 2

    我有一个这样的哈希{55=>{:value=>61,:rating=>-147},89=>{:value=>72,:rating=>-175},78=>{:value=>64,:rating=>-155},84=>{:value=>90,:rating=>-220},95=>{:value=>39,:rating=>-92},46=>{:value=>97,:rating=>-237},52=>{:value=>73,:rating=>-177},64=>{:value=>69,:rating=>-167},86=>{:value=>68,:rating=>-165},53=>{:va

随机推荐