代码改变世界

《快速入门以太坊》学习记录 —转载

2023-12-02 11:00  第二个卿老师  阅读(89)  评论(0编辑  收藏  举报

快速入门以太坊

therscan搜索NFT详细信息:https://goerli.etherscan.io/
搜索测试链和主链:https://chainlist.org/zh
polygonscan链:https://mumbai.polygonscan.com/
铸造NFT:https://thirdweb.com/contracts/new/pre-built/token/nft-collection
合约官方标准示例:https://docs.openzeppelin.com/contracts/4.x/erc721
Remix网页开发环境:https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js
查询分布式存储前缀:https://ipfs.github.io/public-gateway-checker/
查询合约相关信息(NFT):https://thirdweb.com/polygon/0xB2435253C71FcA27bE41206EB2793E44e1Df6b6D/
 
remix合约部署流程:新建合约(源代码文件)——编译(自动)——部署合约——连接钱包——合约操作(根据合约代码的方法操作)
部署合约注意:Environment选择Remix VM(london)本地链,injected provider -metamask为真实测试链;contract选择GameItem-xxx.sol
 

相关说明,参考 https://book.douban.com/review/10326655/

第一章 什么是以太坊

1,以太坊是一个开源的、全球去中心化的计算基础架构,可以执行称为智能合约的程序,它使用区块链来同步和保存系统状态,借助以太币这种数字货币来计量并控制程序执行的资源开销。(虚拟操作系统)
2,公共区块链包含:
  • 一个P2P网络(传播交易和区块)
  • 一组共识规则、一个共识算法(POW,POS这些,以太坊目前是pow,以太坊2.0将是pos)
  • 一组串联在一起的区块(即区块链,存储所有状态转化)
  • 状态机(根据共识规则处理交易,这个状态机既有CPU,也有内存、外存)
  • 消息(形式为交易,代表状态的转移)
  • 激励方案(在开放环境中经济地保护状态机)
上述内容的一个或多个开源实现:客户端
3,以太坊的组件:P2P网络(以太坊主网),共识(pow,最终向pos转化)区块链(levelDB形式),状态机(以太坊虚拟机EVM,类似JVM,能执行字节码),客户端(Geth或Parity)。
4,2013年v神发布以太坊白皮书,2015年7月30日挖出第一个以太坊区块链。
5,图灵完备差不多就是能计算一切可计算问题的意思,其中停机问题是不可计算的,为应对这个问题,以太坊使用gas机制来防止智能合约过度使用资源。
智能合约编译成字节码,类似于汇编语言(每个指令都有确定的运行集群时间和所需要的存储大小),智能合约通过其运行所需要的资源(CPU+存储)可以用gas来作为单位进行衡量(商用分布式区块链系统EOS中也有三类资源:RAM、CPU、NET,不过都是以抵押的形式来购买的,而不会非可逆消耗)
6,每一笔交易都需要消耗EVM的资源,所以也需要gas。可以在交易中设定gas上限来表明你愿意为这笔交易付出的最大gas。如果gas不够,交易会失败且不会退还(建议设大一点)。gas需要以太币购买,价格是浮动的
7,以太坊的智能合约一旦部署就不能改变,只能删除(EOS可以多次重新部署),编写合约简单,但是编写安全的合约难。

第二章 以太坊基本概念

1,以太坊货币单位 1 ether = 10^18 wei,wei是最小可拆分单元
2,账户:以太坊的全局“共享状态”是有很多小对象(账户)来组成的,这些账户可以通过消息传递来与对方进行交互。每个账户都有一个与之关联的状态(state)和一个20字节的地址(address)。在以太坊中一个地址是160位的标识符,用来识别账户
外部拥有的账户,被私钥控制且没有任何代码与之关联
合约账户,被它们的合约代码控制且有代码与之关联
3,区块链数字钱包是管理区块链节点的密钥和地址的工具,它并没有真正的存储货币资产,而是作为与区块链交互的工具,可加载区块链账本数据。如果要更换钱包:直接导出私钥到新钱包,一般钱包越流行,越可靠,建议把ETH放在多个钱包的多个账户里,分散风险。
4,秘钥最好空气隔离,建议使用密码管理器(如1password,其实Apple的iCloud钥匙串也是不错的)笔纸。
5,发送一笔普通的交易需要21 000 gas
6,设计以太币是用来支付智能合约的,智能合约是运行在EVM之上的计算机程序。以太坊网络的每个节点都运行着EVM的副本,用于验证合约的执行,以太坊区块链则记录了这台世界计算机在处理交易和智能合约时所发生的所有状态的更改。
7,在metamask中只能创建EOA(外部账户),不过,合约账户也能进行ETH的转发,当交易目标是合约地址时,它会导致该交易在EVM中运行,使用交易和交易的数据作为其输入。除了以太币以外,交易还可以包含指示合约中要运行的特定函数以及要传递给函数参数的数据。通过这种方式,可以调用合约里的函数。
8,solidity中一个合约类的回退函数或叫默认函数为:function()public payable{}其能在一些特殊的情况下被调用:调用合约的交易没有指定哪一个函数、合约本身没有任何函数、交易没有包含任何数据。
9,将合约部署到以太坊区块链上是靠构造一笔特殊的交易,将合约的字节码作为交易的数据,交易的地址是0x0000...0零地址

第三章 以太坊客户端

1,区块链2.0的标志是多了EVM,也多了一个叫做‘智能合约’的特性
2,以太坊客户端包括屏p2p网络通信模块(包括加密模块)、共识模块、EVM状态机、ETH/ETC区块链。所有以太坊客户端组成了以太坊主网,由于客户端的区块链数据——账本以及P2P网络所不同(网络不同必然导致产生的数据不同,所有区块链数据不同),那就处于不同的网络中,比如ETC经典主网、ETH主网,其中网络不互动,于是其上的币无法通用,除非通过跨链技术。
3,以太坊客户端主要有6种实现方式:GO——Geth;Rust——Parity;C++——cpp-ethereum;Python——pyethereum;Scala——mantis;Java——Harmony。只要符合以太坊黄皮书标准,就能进行交互,也有能力接入以太网主网。
4,标准客户端(比特币核心)包含钱包、矿工、区块链数据库、以及P2P网络上的路由节点。以太坊的轻客户端类似于比特币的轻节点(SPV),远程客户端类似于钱包,但多了一个提供API的功能。

第四章 以太坊背后的密码学

1,大部分情况下,私钥以加密形式保存在钱包软件所管理的文件中
2,椭圆曲线加密就是依靠椭圆曲线来定制了一套新的加减乘除运算,以太坊的哈希函数是Keccak-256(SHA3的原始版本),以太坊地址是由公钥经Keccak-256计算后得出的后20位16进制。

第五章 钱包

1,钱包功能
  • 管理公私钥及地址
  • 跟踪账户的余额
  • 创建并签名交易
  • 部分有与智能合约交互的功能,比如管理ERC20代币
  • 部分是DApp的入口,能解析前端以及和智能合约交互

第六章 交易

1,交易是以太坊作为‘世界计算机’的唯一输入,是由外部账户发出的经过签名的消息,是唯一触发区块链状态改变,或触发EVM上的合约执行的东西
2,交易的标准格式,包含内容有:nonce,gas price,gas limit,receipt,value,data,v/r/s(椭圆曲线签名的三部分)。由vrs可以得到交易发起者私钥的数字签名,由此可以知道发起者的地址。nonce是交易发起者目前记录在链的交易次数,是为了防止重放工具的,也能让交易变得有序。
3,如果gas耗尽,交易失败,所有状态回归,gas不会退款,gas limit可以设稍微高一点,交易也可能是和智能合约的交易,不立刻扣除,交易结束才会被真正扣除这一笔钱,最终的手续费 = 实际消耗的gas x gas价格 = 矿工费,通过编译的字节码后,统计的指令数量来计算。以太坊的gas机制类似于按流量收费,而EOS的资源租赁模式类似于按宽带收费。
4,以太坊在构建交易的模块中没有进行receipt地址的合法性验证,不存在的地址类似于销毁。
5,value和data,只有value的交易是支付(转账)交易,有data的交易大多是合约调用交易。即没有data也没有value的交易可能只剩为了浪费gas
6,部署合约也是构建一个交易,此时交易的data必须是合约的字节码、交易的地址receipt地址必须是0x0,零地址不输入任何人,向其发币代表销毁。
7,交易的签名,作用有:身份认证、不可否认、数据完整性。对某个交易签名其实是对交易的哈希进行签名,可以离线签名。通常交易的创建、签名、广播、都是在一个操作中完成的,也可以分开。
8,每个以太坊节点维护了至少13个与它直接相连的其他节点,称为邻居,默认广播所有的验证数据。
9,可以通过智能合约实现多重签名的功能

第七章 智能合约与Solidity

1,智能合约是不可改变的计算机程序,运行在以太坊EVM上,即以太坊去中心化计算机。
2,合约账户没有私钥,理论上不被任何外部账户控制。是去中心化的,部署者可以把自己的特权写到应用层。
3,部署的合约永远不会自己执行,都是来自外部的合约账户所创建的交易触发的。
4,以太坊是单线程的,没有并发执行,交易是原子性的,也就是说无论一个交易调用多少个合约,都是一个整体,合约无法被重新部署,只能删除清空EVM的存储,不会改变区块链上的交易记录
5,编程语言分为声明式(函数式)和指令式的(过程式),及混合式,solidity在以太坊上最流行
6,solidity数据类型:bool,int uint int8... int256(默认是256位),fixedmxn ufixedmxn(固定小数点的浮点数),address,bytes...bytes32,bytes string,enum,uint32,struct,mapping,seconds,minutes,hours,days,wei finney szabo ether。。。。
预定义的全局变量和函数:交易/信息的上下文msg,交易的上下文tx,区块的上下文block,地址对象address,内建函数addmod、mulmod、keccak256、sha256、sha3、ripemd160、ecreover、selfdestruct、this,合约定义interface、library
函数:function functionName([paras]){public|external|internal|private}[pure|view|payable][modifies][returns(returns type)] 解释:public,默认,可以被外部账户的交易、其他合约、本合约调用;external:不能在本合约内部被调用;internal:只能被本合约、本合约派生的后代合约调用;private:只能被本合约调用。pure:这个函数不会对区块链有任何的读、写操作,只是一个工具函数;view(constant):承若不对任何状态进行修改即保证不写区块链,constant将被弃用;payable:未声明为payable的函数无法接受以太币(挖矿奖励和合约销毁退款除外)
构造和销毁:构造函数:可以是与合约类同名的函数,也可以使用constructor(){}来定义。销毁函数:self destruct(address recipient).可以在构造器中写明合约的拥有者,并且将合约的一部分高级权力赋予之,比如调用销毁合约函数的权力
函数修饰符:本质上是一个短函数,用于执行函数正文前的验证、审计操作:modifier checkOwner{require(msg, owner== owner):_;}
合约的继承:使用is关键词。contract child is Parent1, Parent2{}.继承使得每一个合约都变得相对简单,能够聚集在它所处理的具体问题上,这样我们就可以通过模块化的方式来管理所有细节。代码复用和模块化让我们的项目更加简洁、更易读,也更容易进行代码安全性审计。
错误处理:assert、require、revent。第一个和第二个有点相反的意味,一般来说,我们使用assert来判断(源自内部的)输出条件为真的情况,而用require来测试(来自外部的)输入条件。revert用于立即终止合约,并回滚所有状态,产生一个出错信息,会被存到交易的日志里。进行显式检查是一个好的编程习惯,虽然在区块链系统中这会导致额外的gas开销。
事件(event):当每一个交易完成后都会产生一个类似于发票的交易收据。交易收据包含完整的日志条目,记录了交易执行过程中发生的动作。事件用户生成这些日志,对于智能合约来说非常有用。事件对象可以把参数序列化并且记录在以太坊区块链的事件日志中,可在参数之前添加indexed关键字,可以把索引过后的值作为可以搜索或者过滤的哈希表:event Deposit(address indexed from,uint amout);。使用emit关键字把事件相关的数据写进日志:emit Deposit(msg.senfrt, msg.value).
调用其他合(send, call, callcode, delegatecal)其中call会把msg的上下文改变,而delegatecall则不会
一些忠告:避免动态尺寸的数组,这有出发高额gas消耗的风险;尽量少调用其他合约;在js中使用fun.estimateGas()来估算fun的gas开销。最好把gas的开销评估作为开发合约的一个环节,这样可以避免合约部署到主网后发生高额gas开销这些之前没有想到的问题。

第八章 智能合约与Vyper

Vyper比Solidity更安全,是在牺牲Solidity的一些特性的基础之上的:Vyper无修饰符语法、不支持类继承、不支持函数重载、不支持隐式类型转换(只能用convert函数来显示转换)、使用装饰器替代{public/private/constant/payable}、每一个独立的Vyper合约只能包含一个Vyper文件。以牺牲灵活性来实现正确性

第九章 智能合约安全

1,安全设计原则:最小化/最简单,用最小的复杂度和最简单的代码来实现同样的功能。代码重用,代码质量,可读性和可审计性,测试覆盖率
2,部分漏洞:重入,算术溢出,意外的以太币,DelegateCall,默认的可见性,无序错觉,外部合约引用,短地址/参数攻击,未检查的调用返回值,竞争条件/预先交易,拒绝服务,区块时间操纵,小心使用构造函数,未初始化的存储指针,浮点数和精度,Tx.Origin验证,合约程序库。

第十章 代币

1,代币就是token,工具型代币是指用来支付某个服务、应用或资源的代币,而权益性代币是指代表了一个初创公司股权的代币
2,技术本质上说,以太币的转账操作是在协议级(平台自身支持)处理,而二级代币的交易在智能合约级处理
3,ERC20必须实现以下函数和事件:totalSupply、balanceOf、transfer、transferForm、approve、allowance(配额)、Transfer(转账事件)、Approve(审批事件)
4,ERC721(NFT 非可替代性代币)

第十一章 预言机

1,预言机是一个抽象计算机。用例研究决定型问题。可以被视为一个多了个黑盒子(预言者)的图灵机,这个黑盒子的功能是可以在单一运算之内解答待定问题。预言者可解答的问题,可以是任何复杂度的问题,甚至是不可计算问题,如停机问题
2,在区块链中,预言机是一个可以回答链外问题的系统。在理想情况下,预言机是无信任的系统,这意味着它们不需要被信任,因为它们是按照去中心化的原则运行的。通俗点,区块链预言机,其实就是外部世界的数据输入到区块链上需要的接口系统。EVM无法进行I/O操作,考预言机完成。
3,以太坊需要预言机的两个原因:一是EVM内部是确定的,因此无法产生真正的随机数,且外部数据只能作为交易的数据载荷引入。
4,预言机的应用场景。预言机获取网络上的数据,比如足球比赛的数据、黄金的价格,输入给区块链
5,预言机的设计模式,预言机一般包括:从链外的数据源收集数据、使用签名消息在链上传输数据,将数据存入智能合约的存储空间
设计预言机的三种方式:立即获取、发布与订阅、请求与响应。
立即获取:在要用到的时候去即时获取即可,比如查找和认证。大学可以为往届学生的证书设立一个预言机,不过不需要存储完整的证书信息,只需要存储哈希就行了。
发布与订阅:要对预期改变的数据提供有效的服务,其要么由链上的智能合约轮询,要么由链外守护进程监视和更新,比如天气信息,价格馈送,交通数据等,有点类似推送服务。
请求与响应:这是数据空间太大而无法存储在智能合约中的情况,并且用户每次只需要整个数据集的一小部分,这样的预言机可以实现为链上智能合约系统,以及用于监视请求和检索、返回数据的链外基础结构,最后的数据由预言机所有者签名,正面在给定时间内的数据有效性,然后返回给调用者(比如某个发起调用的DAPP)
请求与响应预言机的步骤总结为:1,接受来自DAPP的查询;2,解析查询;3,检查是否提供看付款和数据访问权限;4,从链外数据源检索相关数据;5,使用包含的数据对事务进行签名;6,将事务广播到网络;7,安排任何进一步必要的交易,例如通知等
6,预言机的数据认证:即便被DAPP查询的数据源是权威和可信的,数据在传输过程中被篡改的可能性仍然存在。如何才能信任这个机制?两种常见的数据认证机制是真实性证明和可信执行环节。前者用类似使用数字签名来保证数据完整性的方式保证结果可信,例子如TLSNOTARY Proof,这里需要有一个机构来审计过程可信,所以这个机构也需要是可信的,比如Oracliza预言机,其审计机构是亚马逊网络AWS虚拟机。后者使用的是过程可信,因为数据源是可信的,所以开始可信+过程可信=结果可信,例子有Town Crier,采用基于硬件的安全区来验证数据的完整性,其使用了英特尔的SGX来保证对HTTPS查询的响应可以被验证为可信的,因此我们需要相信英特尔的硬件可信。
7,计算性的预言机。预言机可以是用来请求数据的,也可以是用来进行计算的,因为EVM的计算资源很宝贵,所以如果要进行大规模的计算,则最好用offchain的计算资源来补充。Oraclize是运行在AWX虚拟机中的,可以使用期来进行计算。类似的解决方案还有Cryptlet和TrueBit。
8,去中心化预言机DO。前面所述的都是中心化的预言机系统,都需要依赖可信的权威。作者列出的DO有:ChainLlnk,其由三个关键智能合约(声誉合约、订单匹配合约、数据汇总合约)以及数据提供者的链外注册表组成。通过声誉合约+订单匹配合约来确定提供某次服务的多个预言机,然后汇总合约数据。这样的去中心化方案要面临的一个最大的挑战是:构建数据汇总函数。一般来说可以根据个体预言机声音和表现反馈来提供一个汇总权重。
9,Solidity中提供了Oraclize的预言机编程接口

第十二章 DApp

1,一个Dapp应该包括以下内容:后端(智能合约)、前端(web网页,JavaScirpt+CSS+HTML),数据存储(去中心化地存储用户数据、网页前端文件)、消息通信(通过P2P网络)、名称解析(去中心化DNS)
理论上,一个完全去中心化的应用应该由去中心化服务器(节点)来分发网页前端、通过P2P网络传输数据、通过去中心化存储来存储用户数据、通过区块链(智能合约)存储用户状态、使用去中心化的DNS来解析网页在网络中的地址。(这里对用户状态和用户数据做了区分,状态是少量的数据并且考虑到状态都是由智能合约存储的;而数据是比较庞大的数据,甚至可能是需要用预言机来获取的)
事实上,只要你应用的用户数据存在区块链里,就可以叫做DApp了。很难全方位地完整实现一个DApp
2,后端(智能合约):因为任何操作、存储都特别昂贵,所以应保持合约尽量小。确定一个应用哪些部分需要用到去中心化的功能尤其重要。
3,前端(Web界面):与一般的web应用特别多的区别,都是用JS+CSS+HTML编写的。唯一的区别是在于用户管理上。DApp的用户登都无法通过直接输入账户密码的方式进行,一般都是通过前端拉起钱包应用,然后在钱包里输入钱包的密码来授权的。这样你就不必把你的私钥交给DApp
4,数据存储。因为EVM的性能限制,大多数的DApp利用链下数据存储服务。这种数据存储服务可以是中心化的,也可以是诸如IPFS、Swarm(Geth工具链的一部分)等去中心化的,这两个都是内容可寻址的,内容可寻址的意思是文件的每一小块都被哈希处理,通过这个哈希可以将文件取回。
5,消息通信:Geth中包含Whisper这种P2P消息协议

第十三章 以太坊虚拟机

1,EVM就是一个虚拟机,和JAVA的JVM,微软否认.NET的虚拟机类似。在以太坊中,除了在EOA之间的简单转账交易以外,其他所有涉及状态更新的操作都是通过EVM来计算的。EVM是一个准图灵完备的状态机。因为有了gas机制,这样,停机故障就被解决了。和VirtualBox这样的虚拟机 稍有不同,EVM运行在一个更局限的领域:它仅仅是一个计算引擎,仅提供对计算和存储的抽象。(或者说EVM是一个沙盒,与外界隔离,智能合约代码在EVM里运行时无法进行网络操作、文件I/O或执行其他进程)
2,EVM包含以下部分:一个用来存储程序代码的ROM,加载要执行的智能合约;一个内容可变的RAM(又被称为Memory);一个永久的存储,它是作为以太坊状态的一部分存在的(叫做Storage)。其实还有一个部分,那就是栈(Stack)。Storage、Memory、Stack是EVM上存储数据的三块地方,storage存储最重要的、读写操作最少的数据(storage是实时和区块链统一的),Memory可以存储程序运行时的一些中间数据,stack最多存1024个256位的数据。
EVM从功能上又可以分为合约编译模块、Ledger模块和核心模块。因为EVM无法进行网络操作、文件I/O,所以其实通过添加区块内容,然后区块被P2P网络传输才能实现状态传输和全网统一的。再讲的简单点,EVM的输入一定是交易,输出其实也是交易。EVM不直接和网络中的其他counterpart(即其他节点的EVM)打交道。EVM的能力和一台完整的计算机差距还有很大,EVM就是个工具人,运行智能合约对交易进行操作,交易操作完后输出给P2P模块,P2P模块来完成数据在网络上的传输。
3,EVM的指令大概包括:算术和位运算逻辑操作,执行上下文查询,栈,内存和存储访问,处理流程操作,日志、跳转和其他操作。
4,以太坊的状态。以太坊的状态是基于交易的。交易是EVM的唯一输入,在最高层级,有以太坊世界状态的概念,其是一个以太地址到账户数据的映射,如下图所示
智能合约(的代码)是 上链的,平时是存在区块链里的,属于账户数据的一部分。当你的交易触发了某个智能合约,其被EVM从区块链加载到EVM的ROM,然后从调用的合约账户对应的Storage中加载一些存储的数据(状态),将Memory清零并将区块与其他环境变量相关的信息设置好,如果gas耗尽,则交易失败,nonce还是会+1
5,被编译出来的合约字节码!=被部署的合约字节码(运行时字节码)。这是因为被编译出来的字节码中一部分代码是为了部署而有的。所以字节码是可以被反汇编的,但部署到链上的字节码反汇编出来的代码和写好的Solidity代码还是有所不同的。
6,尽管gas是有价格,但是它既不能被持有,也不能花费,gas仅仅是作为EVM内作为对计算工作量的计量而存在的。
7,负gas消耗,EVM中有2个操作带有负的gas消耗,一个是前面说过的合约销毁——self destruct,会返还24000gas。另一个是将一个非零的存储地址设为0(sstore[x]=0)会返回15000gas。为了避免通过返还机制牟利,交易的最大gas返还数量设定为交易中总共消耗的gas的一半
8,区块的gas上限,一个区块中的交易总共能消耗的最大gas数量,它也限定了一个区块能包含的交易。
区块链的核心功能是去中心化记录的保存与研制,EVM是辅助达到这一目标的

第十四章 共识

1,共识一词是源于分布式系统中的普遍问题即状态同步相关。状态同步指的是分布式系统中的不同参与者全体对单个系统状态达成一致,也叫达成共识。在缺乏可信仲裁者的情况下,所有的争论、骗局以及不一致都要用数学、经济乃至社会技术来协调。而共识算法正是用于兼顾安全性和去中心化的机制。
2,但从一开始,以太坊的创始者们就希望以太坊的共识算法最终能过渡到Pos(2019年的上半年Pos、Staking Economy一度是区块链领域最热门的话题,大量新项目都是用的Pos共识机制)。PoS就是Proof of Stake,即权益证明,以太坊计划使用的PoS算法叫做‘Casper’
3,以太坊的开发有四个阶段:Frontier(2015-07)、Homestead(2016-03)、Metropolis(分为两个子阶段:拜占庭2017-07、君士坦丁堡2019-03)、Serenity(时间未定)。在进入Serenity之后,以太坊的共识变为PoS
什么样的共识是最好的?这个问题正是过去十年大部分分布式系统研究的核心。这完全取决于实际情况,在不同的环境下你需要不同的评价指标。简单来说,区块链系统有三个老生常谈的重要性能:去中心化,完全性,可拓展性。在目前为止,我们的技术还不能使三者兼得,所以选择什么共识,如何设计具体的算法有时是一个trader-off,是一种权衡。
可以理解为民主与效率的一种权衡。完全的去中心化=完全民主,中心化服务器=完全高效,完全民主有弊端,完全高效顾不得民主也有弊端。

第十五章 其他

1,和比特币中的区块是merkle树相比,以太坊的区块结构是Merkle Patricia树