区块链学习笔记Day1:简单智能合约实现
学区块链做的笔记Day1,大部分内容来自《精通以太坊》。
区块链的组件
一个公开的公共区块链通常包含以下组件:
- 一个连接参与各方的点对点网络,用于传播交易和区块数据包,基于标准的“gossip”协议。
- 以交易形式体现的消息,代表状态的转换。
- 一组共识规则,用于管理构成交易的内容以及实现有效的状态转换。
- 一个状态机,根据共识规则交易。
- 一组串联在一起的、由加密算法保证其安全的区块,这些区块是所有已验证和已接受的状态转换的记录日志。
- 一个共识算法,用于在区块链上实现控制的去中心化,这类算法通过强制参与者之间的合作以实现共识规则的有效执行。
- 在博弈论上合理的激励方案(列如:工作量证明、区块奖励),以在开放环境中经济地保护状态机。
- 上述一个或多个开源软件实现(客户端)。
以太坊的组件
点对点(P2P)网络
以太坊运行在Ethereum Main Network上,这是一个通过TCP 30303端口寻址的网络,网络层运行的协议名为-DΞVp2p。
共识规则
以太坊的共识规则,由以太坊黄皮书(见后文中的“扩展阅读”)中的参考标准进行精确定义
交易
以太坊交易是一个网络消息,主要包含交易的发送方、接收方、价值和数据载荷。
状态机
以太坊的状态转换由以太坊虚拟机(EVM)处理,这是一个基于栈的虚拟机,执行bytecode(字节码指令)。被称为“智能合约”的EVM程序采用高级语言(例如Solidity)编写,并编译为通过EVM执行的字节码。
数据结构
以太坊的区块链以数据库(通常采用Google的LevelDB)的方式保存在每一个节点之上,区块链内包含了交易和系统的状态,经过哈希处理的数据保存在Merkle Patricia Tree数据结构之内。
共识算法
以太坊使用比特币的共识模型 Nakamoto Consensus,它使用顺序单一签名块,由PoW加权重要性来确定最长链,从而确定当前状态。但是,有计划在不久的将来转向代号为Casper的PoS加权投票系统。
经济安全性
以太坊当前使用名为Ethash的工作量证明算法,这个算法迟早将被放弃,并切换到PoS。
客户端
以太坊有多个可以交互的客户端软件实现,其中最广泛使用的是Go-Ethereum(Geth)和Parity。
一个简单的智能合约:Faucet
书上用的是Ropsten测试网络,但是这条网络已经被关停了
然后比较出名的几个测试网络已经被薅的不成样子了
所以这里选择用Ganache自己搭一个测试网络进行测试
搭建Ganache的教程网上有很多,这里不细讲
合约代码
1 | // 编译时的版本要对上 |
这里的 _receive() external payable {}_ 在书中为 _function() public payable {}_ 描述为:
这个函数被称为回退函数或默认函数,它会在一些特殊情况下被调用,比如触发这个合约的交易没有指定调用哪一个具体函数,或者合约本身没有定义任何函数,再或者交易没有包含任何数据。合约可以有一个这样的默认函数(没有名字),通常也使用这个函数来接收以太币。这也是为什么这个函数的定义包含public和payable属性,这意味着这个合约可以接收以太币。如函数声明的空花括号所显示的,除了接收以太币,这个合约什么也不会做。如果我们发起一个针对合约地址的交易,就像是把合约地址当作钱包使用,这个函数就会处理。
receive()函数:
- 一个合约至多含有一个receive()函数
- 没有function关键字
- 必须含有payable关键字
- 没有参数,没有返回值
- 可见性必须声明为external
- 允许使用modifier修改器
- 该函数通过.send()和.transfer()转发以太币
- 若想要让你的contract(即合约账户)接收以太币,在未定义fallback() external payable{}函数时,需实现receive()函数
- 在gasLimit允许范围内可执行复杂操作
还有一个专门的回退函数
fallback()函数:
- 一个合约至多含有一个fallback()函数
- 没有function关键字
- payable关键字是可选项,取决于该函数是否需要接收以太币
- 该函数可代替receive()函数以实现合约接受转发以太币的功能
- 可见性必须声明为external
- 允许使用modifier修改器
- 在gasLimit允许范围内可执行复杂操作
具体使用先不管,大概可以看成合约用于存放以太币的地方,可以对合约内的以太币进行转账等操作。
编译部署合约
在这可以看到编译好的程序的详细信息
部署上程序后因为使用的是本地的Ganache作为测试网络
所以要查看已经部署上的合约可以上Ganache客户端进行查看
向合约充值
直接向合约地址转账
可以看到合约内的钱增加了
从合约提币
这里试了半天,一直出错
搞了半天才发现是这里的限制
100000000000000000wei 才 0.1eth
这里改成小于这个数就可以提款成功了
1e18wei = 1eth
顺便一提,如果数太大导致没有转账,但是交易还是进行了,也就是说手续费会照样扣,所以如果不是自己搭建的测试网络,在交易前还是先确认好交易信息比较好(