【智能合约笔记-01】入门智能合约|使用智能合约实现发币、转账、查询等功能
01-入门智能合约
前言
之前使用web3js调用了很多合约进行交互,那么如果想深入了解的话,还是需要学习一下合约相关的知识,这是一篇入门笔记,能让我们对合约有个大概的认知。
通过这篇文章你能了解到:
- 如何存储数据上以太坊链
- 如何发行一个自己的Token(币)
- 实现代币的增发
- 实现代币余额的查询
- 实现代币的转账
准备工作
可以使用remix编辑器和solidity文档
简单的智能合约
存储链上数据
目标:
- 能在EVM(以太坊虚拟机)存储一个数据
- 能查询该数据
1 | pragma solidity ^0.4.0; |
把代码复制进remix编辑器,点击 complite进行编译 👇
编译成功之后,需要将代码部署。切换点击deploy进行部署 👇
部署成功之后就会看到自己刚刚写的测试方法,有一个set方法,需要传入一个unit256类型的数据。
同时还有一个get方法
注意这里按钮的颜色,set是黄色,get是蓝色。
蓝色代表查询,不需要付gas费用,而黄色set代表设置,对链上数据进行更改,就需要付gas费用
我们可以直接点击get,就可以直接调用该方法。
就可以看到控制台会输出这些信息,在decode output里面可以看到这个数字现在默认为0
然后我们使用set调用一下该方法:
如图所示,我将一个数字为77设置给了这个存储storedData。然后需要花费gas,最后数字也变成了77,再次调用get,就能看到该数字为77了
至此,我们基本上了解了合约简单的编写,到编译,再到部署和调用的整个过程了。
发一个币
目标:
- 我们可以无限量发币
- 只有合约创建者可以发币
- 币可以发送给别人
1 | // SPDX-License-Identifier: GPL-3.0 |
备注说明
基本上代码上都写了注释,但是有几个特别的地方。
一个是mint()
方法中的中的 require
,一个是 send()
方法中的revert
这两处不是很明白。
错误处理:Assert, Require, Revert and Exceptions
便利函数 assert
和 require
可用于检查条件并在条件不满足时抛出异常。assert
函数只能用于测试内部错误,并检查非变量。 require
函数用于确认条件有效性,例如输入变量,或合约状态变量是否满足条件,或验证外部合约调用返回的值。 如果使用得当,分析工具可以评估你的合约,并标示出那些会使 assert
失败的条件和函数调用。 正常工作的代码不会导致一个 assert 语句的失败;如果这发生了,那就说明出现了一个需要你修复的 bug。
还有另外两种触发异常的方法:revert
函数可以用来标记错误并恢复当前的调用。 revert
调用中包含有关错误的详细信息是可能的,这个消息会被返回给调用者。已经不推荐的关键字 throw
也可以用来替代 revert()
案例解释
require 等同于 if throw
1 | pragma solidity ^0.4.22; |
同样作为判断一个条件是否满足的函数,require会退回剩下的gas,而assert会烧掉所有的gas
编译部署
按照上面方法,我们进行compile 和 deploy
成功之后就会看到这些方法部署了。
我们是用0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
这个账号部署的,所以先用blances()
方法来看下有多少代币余额。
没有任何余额。
然后通过mint我们发行一些余额。
mint()
方法需要2个参数分别是接受的地址和数量
我直接用发行合约的地址0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
以及传入1000000000000000000
wei,也就是1eth
然后再次调用balances()
方法查看我们该账户的余额,就可以看到有1000000000000000000
这么多个了。
之后调用转账方法:
这里有多个账号,我们可以直接切换。拿到2个账号
账号1:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
合约创建账号
账号2:0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
需要转账的账号
我们调用send()
方法,向0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
账号转账100
成功转账100个代币
调用查询方法,账号2正好有100个代币.至此就完成了发布,以及一系列转账等操作了。
通过以上练习,大概能初步理解solidily了
以太坊虚拟机
上述这些都是跑在以太坊虚拟机上的,大家可以简单了解下以太坊虚拟机相关的知识:
注意的点:
Gas
一经创建,每笔交易都收取一定数量的 gas ,目的是限制执行交易所需要的工作量和为交易支付手续费。EVM 执行交易时,gas 将按特定规则逐渐耗尽。
gas price 是交易发送者设置的一个值,发送者账户需要预付的手续费= gas_price * gas
。如果交易执行后还有剩余, gas 会原路返还。
无论执行到什么位置,一旦 gas 被耗尽(比如降为负值),将会触发一个 out-of-gas 异常。当前调用帧(call frame)所做的所有状态修改都将被回滚。
所以在web3js调用的时候,也要注意gas费用,之前经常碰到gas太低而失败的例子。