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

1智能合约简单了解

1.1智能合约是什么

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

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

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

1.2智能合约的技术特点

1.2.1数据透明化

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

1.2.2不可篡改

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

1.2.3永久运行

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

2Solidity语言初步学习

2.1IDE的使用

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

2.2第一个智能合约helloworld

2.2.1创建项目

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

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

2.2.2编译运行

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

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

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

2.3第二个智能合约

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

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];}}