课程链接 https://www.coursera.org/learn/smarter-contracts/home/week/4
为自己学习记的笔记,翻译可能存在问题,望谅解。
Best Practices
Best Practices: Evaluating Smart Contracts
评估智能合约
到目前为止,我们已经讨论了智能合约的设计和开发。 本模块将重点介绍最佳实践。 我们将从有关评估基于区块链的解决方案是否适合您的问题的警告性注释开始。 然后,我们将在设计Solidity智能合约时讨论一些最佳实践,这些合约的重点是数据功能及其可见性修饰符和访问修饰符。 我们将跟进与Remix IDE相关的最佳实践。 完成本模块后,您将能够在设计基于区块链的应用程序时列出最佳实践。 说明使用Solidity和Remix IDE通过智能合约设计解决方案的最佳实践。
区块链不是所有应用程序的解决方案。什么时候使用区块链?
确保您的应用程序需求需要区块链功能。
区块链更适用于:
1. 分散的问题。参与者拥有资产并且不在同一地点。
2. 无需中介的点对点交易。
3. 超越未知同行之间的信任范围。
4. 要求在普遍加盖时间戳的不可变分类帐上进行确认,验证和记录。
5. 由规则和策略指导的自动化操作。
确保您的应用程序需要区块链上的智能合约,了解智能合约对链中的所有参与者都是可见的,并将在所有完整节点上执行。当您需要基于规则,法规,政策或强制实施的集体协议时,就需要智能合约,并且必须记录其决策和出处。
best practices
1)智能合约不适用于单节点计算。 它不能替代您的客户端服务器或固有的无状态分布式解决方案。 保持智能合约代码简单,一致且可审核。让它很好地解决单个问题,避免设计和编码错误。让状态变量和智能合约中指定的函数解决单个问题。 不要包含冗余数据或不相关的功能。
2)通过使用自定义函数修饰符而不是内联if-else代码来检查函数执行的前后条件,使智能合约函数可审计。
智能合约通常是大型分布式应用程序的一部分,需要区块链提供服务的部分。区块链不是一个数据存储库 data repository ,
3)在智能合约中只保留必要的数据。
当然,它是不可变的分布式交易帐本。
回想一下,区块链还管理状态转换,并在每个块的标题中维护状态 state 哈希,交易 transaction 哈希和收据 receipt 哈希。
这些确实是依赖于应用程序的开销。 鉴于这些特性,最好的方法是分析应用程序数据并将其分离为链上链外数据。 设计智能合约的状态变量,以有效存储链上数据。 保留脱链数据由更高级别的应用程序管理。 例如,与其保留并输入500页的公共法律文档,不如保留有关文档的元数据,包括安全散列以保护文档的完整性。
设计智能合约
best practices
1)使用适当的数据类型 Use appropriate data types
Ethereum虚拟机,是一个为整数计算优化的两个56位处理器。它有一个堆栈机器,用于执行有限的一组应用程序代码。考虑上一模块中讨论的投票 ballot 示例。例如, proposal 的字符串类型的变量名可能很昂贵,因为智能合约中的字符串是动态大小的变量。建议使用整数标识代替 proposal 的可变字符串名称。 此ID用作投标阵列的索引。这也是 winningProposal 函数返回的数字。然后,如果需要,链外的用户级应用程序可以将ID映射到 proposal 名称。
2)确保您使用整数算法 integer arithmetic 来满足大多数计算需求。与普通64位处理器相比,EVM的256位处理器确实非常大,容器大小的位数每增加一倍,值的范围就会成倍增加。Solidity还提供了从8位Uint8到256位Uint256的各种大小。
3)了解数据的公开可见性修饰符。 所有状态变量均创建为私有。 区块链上的任何变量都是可见的,而与可见性修改器无关。。您必须明确声明变量是公共的。 将变量声明为公共变量 public 后,Solidity编译器会自动创建一个getter方法来查看变量的值。 在合约内部,变量作为数据访问,在外部它作为函数访问。请注意访问公共数据和getter方法的这种差异。
4)维护智能合约中不同函数类型的标准订单 standard order 。根据 Solidity 文档中的可见性说明, 推荐的智能合约中函数的顺序为: 构造函数 constructor,后备函数 fallback function,外部 external,公共 public,内部 internal,私有 private。 在一个分组内,最后才是常量函数 constant functions。
5)函数可以有很多不同的修饰符。函数具有可见性修饰符以及预定义和自定义访问修饰符。 该功能的可见性修饰符应位于任何自定义访问修饰符之前。通过在空格分隔的列表中指定它们来应用到一个函数的多个修饰符,并按给出的顺序进行评估。 因此,如果一个修饰符的输出依赖于另一个修饰符,请确保按正确的顺序对其进行排序。
例如:
6)发送值时,请使用Solidity定义的 payable 修饰符。只有通过 payable 函数,账户才能将值发送到另一个地址。
在下面的示例中,bid 函数是为拍卖项目出价,只有在函数是 payable 时,交易出价调用 bid 才可以发送B。
7)注意函数中语句的顺序。第一个 withdraw 函数首先检查条件,然后允许退出,第二个函数首先具有退出代码,然后进行条件检查。 与此类似,当智能合约在移动以太币之前被杀死时,导致仿冒钱包损失了数百万个以太币。
8)使用修饰符声明来实施规则。
使用函数修饰符:
实施规则,政策和法规。
为所有可以使用功能的人实施通用规则,
以声明方式验证特定于应用程序的条件,
提供可审核的元素,以验证智能合约的正确性。
9)在智能合约中使用 events 进行通知。 在智能合约执行期间,尤其是长期运行的合约中,使用事件记录重要的里程碑。 事件最多可以包含三个索引参数,这些参数可以有效地用于搜索区块链中的事件。与使用外部函数轮询智能合约的客户端应用程序不同,事件可以将信息推送到应用程序,从而将监听器设置为特定的事件。
10)注意时间变量 now 。now 是该块的块时间戳的别名,指示何时开采和记录该块及其中的事务的通用时间。 如选票示例所示,now 可以将变量用于和经过的大致时间比较。 但是,在应用程序逻辑中将其用于计算不是一个好习惯。 而且,如果需要精细的时间,变量现在可以提供精确到秒的时间,您可能不得不诉诸其他机制。
11)使用安全哈希来保护数据。回想一下,哈希是区块链中非常重要的功能。 所有人都可以查看区块链中的数据。 这意味着我们可能要保护哈希值,以保护其可见性。 Solidity为标准的安全哈希函数提供了多种内置函数。 Keccak,SHA-256,RIPEMD-160是可用于哈希应用程序数据的Solidity函数。
Remix Web IDE
Remix 每周更新非常频繁。但是它为您的所有开发需求提供了一个Web ID。
best practices
1)注意 Remix 静态分析。在 Remix 编译时,注意静态分析警告。其中许多对于开发更好的智能合约非常有用。
2)注意 Remix 控制台细节 console details
3)查看 Remix 的编译细节 compile details
Remix编译器是即时编译器。在编辑器窗口中输入代码时,其语法会使用红色按钮X检查并标记所有错误。单击它可获取有关该错误的更多详细信息。这是有用的信息,可以帮助您随时学习语法,并且可以进行更正。编译后,当您单击详细信息按钮时,您可以看到由编译器进程生成的所有工件 artificals 。
4)Remix transaction log for debugging。Remix 面板上有一个软盘图标。 单击此按钮时,可以看到所有已执行事务的JSon版本。 可以保存此Json文件,并将其用于研究交易明细,还可以使用智能合约代码调试任何运行时问题和逻辑问题。
此列表并不涵盖所有最佳实践。 随着专业化的进行,我们将收集更多信息并将其添加到此列表中。
阅读材料
Ethereum Smart Contract Security Best Practices
Beyond Smart Contract Best Practices for UX and Interoperability
Solidity Smart Contract Security Best Practices
测试题
*第10题后两个选项都不对,我也没有再试别的选项。(懒癌患者-。-)
课程要点
第一周:智能合约基础
以太坊区块链中的合约有:
1. 编译版本指定 Pragma directive
2. 合约名称 Name of the contract
3. 定义合同状态的数据或状态变量 Data or the state variables that define the state of the contract
4. 收集功能以执行智能合约的意图 Collection of functions to carry out the intent of a smart contract
5. Other items we will discuss in later lessons.
Remix是一个Web集成开发环境(IDE),可在以太坊区块链上创建,部署,执行和探索智能合约的工作。
Remix is a web Integrated Development Environment (IDE) that creates, deploys, executes and explores the working of smart contracts on the Ethereum blockchain.
两个简单的智能合约:
1. Greeter
2. One integer storage: SimpleStorage
设计一个智能合约的步骤:设计 Design,编码 Code,测试 Test。
Remix Solidity编译器会生成一些工件,例如:
1. 合约名称 Name of the contract
2. 为EVM上的合同“创建”执行的字节码 Bytecode executed for the contract “creation” on the EVM
3. ABI:应用程序二进制接口,详细介绍功能,参数和返回值 ABI: Application Binary Interface, details functions, parameters and return value
4. Web3部署模块,提供用于从Web应用程序调用智能合约的脚本代码 Web3 deploy module that provides the script code for invoking the smart contract from a web application
5. 执行该功能所需的 gas 估算 Gas estimates for the execution of the function
6. 智能合约的实际运行时字节码 Actual runtime bytecode of the smart contract
可以通过以下方式部署智能合约:
1. Remix IDE
2. 另一个智能合约
3. 命令行界面 A command line interface
4. 另一个高级应用 Another high level application
5. Web应用程序。
使用Remix IDE完成部署过程:
1. 您在Remix IDE中输入智能合约代码并进行编译。
2. Remix会生成一些伪像,如前所述和图片所示。Remix generates several artifacts as discussed earlier and as shown in the picture.
3. 为了便于部署,remix为我们提供了web3部署脚本,其中包含字节码,应用程序二进制接口(ABI),帐户详细信息。
4. 要部署智能合约,我们只需执行此脚本即可。
5. 部署完成后,将通过哈希创建者的帐号和随机数生成地址。
6. 为了与智能合约进行交互,我们将使用智能合约地址,ABI定义和函数哈希。
第二周 Solidity
智能合约的详细结构:
1.数据或状态变量
2.功能:允许使用几种类型的函数
构造函数 Constructor(默认或用户指定;仅一个,表示它不能重载)
后备函数 Fallback function(这是匿名功能的强大功能,我们将在本课程的稍后的最佳实践模块中进行讨论。)
查看函数 View functions
纯函数(状态不变,它计算并返回一个值;例如:数学函数)
公共函数(可从外部通过交易访问,状态更改记录在公元前)
专用函数(仅可通过当前合约访问)
内部函数(可在当前合约和继承合约内部访问)
外部函数(只能从智能合约外部访问)
3.用户定义的struct和enum类型
4.修饰符 Modifiers
5.事件 Events
“function” 是所有函数开头的关键字
参数 Parameters 是任意数量的对{type,identifier}。 例如。 单位计数
Return参数:返回值可以指定为一对{type,identifier}或仅{type}。 如果仅指定类型,则必须使用return语句显式返回。
如果在returns语句中指定了类型和标识符,则该函数中标识符发生的任何状态更改都会自动返回。
与仅允许一个返回值的普通编程语言不同,可以返回任意数量的值。 例如,可以为多个变量,年龄,性别分配函数的返回值
1 Ether is 10^18 Wei.
Solidity 是一种高级语言,是Javascript,Java和C的组合
Bidder智能合约设计包含三个项目:合约名称 Name of the contract,数据/状态The data/states,功能 The functions
“Address”是一种特殊的由Solidity定义的复杂数据类型,可以容纳20字节的以太坊地址。 地址是智能合约的基础。
“Mapping” 是一种非常通用的数据结构,类似于<key,value>存储。 可以将其视为哈希表。
“Message” 是特定于智能合约的复杂数据类型。 它代表可用于调用智能合约功能的调用。
“Struct” 是一组相关数据的复合数据类型,可以由单个有意义的集合名称引用。
“enum” 或枚举数据类型允许使用用户定义的数据类型,这些数据类型具有有限的一组有意义的值。
智能合约交易的主要目的是执行功能。
您可以将修饰符视为保护功能的看门人,因为它可以更改函数的行为
第三周:put it all together
Solidity 具有 revert() 函数,该函数会导致状态恢复异常。
此异常处理将撤消对当前调用中的状态所做的所有更改,并撤消事务,并向调用者标记一个错误。
Event 用于向客户端应用程序(用户界面或交易监听器)指示已达到重要的里程碑。
监听器代码可用于:
1. 追踪交易
2. 通过事件参数接收结果
3. 发起拉取请求以从智能合约接收信息。
主席是智能合约的创建者。他/她将是唯一可以登记选民的人。
函数列表:
1. 构造函数 Constructor 是一种用于创建智能合约的函数。在Solidity中,与常规的面向对象语言不同,只能有一个构造函数。另外,构造函数与合同具有相同的名称。调用构造函数的消息的发送者是主持人。
2. 注册函数有注册选民的功能。只有主席可以注册选民。注册消息的发送者必须是主持人。
3. vote 函数,其中包括主席在内的选民可以对提案进行投票。
4. Winningproposal是确定中标方案的最终功能,可以由客户端应用程序调用。
阶段有四个不同的阶段:初始化,注册,状态和完成。在部署智能合约时,该阶段将初始化为init。然后,在构造函数中,将init更改为reg阶段。注册期结束后,阶段将更改为投票。经过投票持续时间后,该阶段将设置为“完成”。
第四周 Best Practices
区块链并不是所有应用程序的解决方案。确保您的应用程序需求需要区块链特性区块链解决方案是最适合具有以下特征的应用程序:
1. 分布式的问题,这意味着参与者拥有资产并且不在同一地点,
2. 涉及没有中介的点对点交易,
3. 超越未知同行之间的信任范围。
4. 要求在普遍加盖时间戳的不可变分类帐上进行确认,验证和记录。
5. 由规则和策略指导的自动化操作。
确保您的应用程序需要区块链上的智能合约。
保持智能合约代码简单,一致且可审核。
区块链不是数据存储库。 在智能合约中仅保留必要的数据。
确保满足大多数计算需求使用整数 integer 算法。
根据Solidity文档中指定的可视性,为智能合约中的不同功能类型维护标准订单。
智能合约中建议的功能顺序为:
1. constructor
2. fallback function
3. external
4. public
5. internal
6. private
在分组中,将常量函数放在最后。
发送价值时使用Solidity定义的“payable”修饰符
注意函数内部的语句顺序
使用修饰符声明来实施规则
在智能合约中使用事件
使用安全哈希来保护数据
*由于我没有购买课程,所以部分测试题和代码提交不了。以上内容是作为课程旁听生学习时做的记录。因为没有中文字幕,所以很多名词和句子的理解可能翻译有问题。这是为自己学习记录所用。