区块链Dapps Coursera(第三周)设计改进

课程链接 https://www.coursera.org/learn/decentralized-apps-on-blockchain/home/week/3
为自己学习记的笔记,翻译可能存在问题,望谅解。

设计改进Design Improvements

目录

Solidity 特性 Solidity Features

Design Improvements: Solidity Features (Part 1)

Design Improvements: Solidity Features (Part 2)

事件处理 Event Handling

Event Handling (Part 1)

Event Handling (Part 2) (Coin Demo)

Oraclize


Solidity 特性 Solidity Features

Design Improvements: Solidity Features (Part 1)

本模块旨在使 Dapp 在区块链方面更好,更高效,更实用。 有一些改进有助于围绕智能合约设计实用的分散式应用程序。这里提出一些改进:
1. 不将不必要的数据存储在区块链中。回想一下,区块链并不是一个数据存储库。
2. 有没有办法记录链上发生的事件? 忘记操作完成的通知或是否需要注意。
3. 智能合约无法访问外部链接。
区块链Dapps Coursera(第三周)设计改进_第1张图片

回想一下,纪元时间是从1970年1月1日起的通用时间(以秒为单位)。那么我们如何解决从智能合约访问外部资源的问题呢? 我们将在本模块中解决这些问题。

学习目标:
1)能够列出其他一些功能,这些功能可以使智能合约变得高效,实用和有用。
2)重用代码并应用智能合约的层次结构进行专业化 specialization 和泛化 generalization。
3)说明事件的使用并将事件推送到订阅应用程序。
4)解释使用以oracles命名的智能合约的用法。
区块链Dapps Coursera(第三周)设计改进_第2张图片

如您所知,软件开发是增量和迭代的,每次迭代都比以前有所改进。 您是否知道安全性是经过深思熟虑的,并且已被改进为HTTP协议? 从HTTP到HTTPS。请参阅RFC 2660和RFC 2818中这种改进的开始。管理以太坊协议的持续改进的以太坊改进建议框架EIP是迭代过程改进的一个很好的例子。 回想一下,EIP与Internet工程任务组(IETF)的RFC评论请求类似。

学习目标:
最小化区块链中不变账本上的足迹。
管理智能合约的所有权和寿命。
使用继承中的接口来组织相关的智能合约,以进行重用和正确的类型分类。
区块链Dapps Coursera(第三周)设计改进_第3张图片

为了最大程度地减少区块链上的占用空间,让我们考虑数据的存储与内存属性。 默认情况下,变量在智能合约中定义的所有状态更改均作为状态 state 保存在区块链上。使用状态变量的Merkle树或Patricia Merkle树计算以太坊块头的状态哈希。我们只希望将一小部分数据作为来源provenance,治理 governance 和不变性 immutability 的状态保存在区块链上。因此,我们的目标是最大程度地减少智能合约的状态 state 或 footprint,并降低 gas 成本。

实现此目的的方法之一是正确使用 memory 和 storage 关键字。 memory 和 storage 确实是统一性语言中的关键字,它们的含义与常规计算系统中的含义相同。 memory 是RAM中的临时内存, storage 是指永久存储在永久存储设备(如硬盘)中的存储。

区块链Dapps Coursera(第三周)设计改进_第4张图片

内存是临时的,是函数调用之间的竞争。 内存是一个字节数组。 使用以太坊会更加便宜。 由于一切都会导致 gas point,因此我们必须意识到这一点。 每个合约都分配有一个存储空间,并且该存储是永久性的。 其中的值在函数调用之间保持不变。 存储是键值和键值各32个字节的键值存储。 所有存储数据均视为状态,并用于头的状态哈希路由的计算。使用内存位置时,几乎不会产生猜测点,1-3,而存储成本则高达数千点。 设置2万点,更改值5,000点,依此类推。
您可能想知道为什么我们如此关注这种内存与存储的差异。 可以理解,智能合约是全球性的,每个完整节点中都存在一个副本。 状态足迹哈希存在于每个块中。 我们不需要关于不变总账的不必要的细节。我们可以通过多种方式来管理内存与存储的权衡。 在这里,我们将仅考虑复合数据结构和数组。 在 solidity 智能合约中,默认情况下为struct和array分配存储而不是内存,即使它们是函数本地的。
区块链Dapps Coursera(第三周)设计改进_第5张图片

当将结构或数组用作函数中的参数或局部变量时,请将它们声明为内存变量 memory variables 。 如果不存在内存属性 memory attribute,则临时 变量投资者 variable investors 将成为浪费状态变量空间的存储变量。
区块链Dapps Coursera(第三周)设计改进_第6张图片

由于我们宣布投资者为存储类型,因此其30 x 20字节的空间位于临时存储器中,是智能合约的永久存储空间。我们都知道,一旦部署智能合约,便是永久不变的。 我们在EVM上节省了600字节的存储空间。空间效率的提高不仅适用于区块链上的一个节点,而且适用于每个完整节点。在使用统一语言开发智能合约时,请考虑对任何瞬态数据 transient data 使用存储变量。 仅将存储变量用于需要保留在区块链上的内容。 现在,让我们进入我们将要讨论的第二个改进。 如何取消或删除智能合约。

Design Improvements: Solidity Features (Part 2)

你有没有想过,如果部署的智能合同已经过时了怎么办?

考虑一下这种情况,在美国,2016年的所得税法律是无效的。我们可能已经为此部署了智能合约。因此,智能合约现在已经没用了。这些智能合约会收取多少钱的税呢?当我们部署代表新税法的智能合约时,我们可以将这些智能合约的所有权更改为受信者帐户吗?

这些问题不仅需要美国国税局(Internal Revenue Service)认真考虑,任何可能部署区块链和DApp smart contract解决方案的企业或组织都需要认真考虑。

回想一下,智能合约是由地址标识的。
它可以表示一个令牌、一个组织、一个人、人或其他以及相关的逻辑规则和操作。
智能合约具有所有者。即智能合约的创建者。
它具有价值或以太币余额。 它的所有权可能会更改,或者可能必须删除。
区块链Dapps Coursera(第三周)设计改进_第7张图片

考虑到所有这些复杂的属性,如何管理智能合约呢?要删除或终止智能合约,solid提供了一个名为 self-destruct 的函数。根据默认的区块链协议,这个调用是不可逆的。一旦被杀死,smart契约将不能被恢复或访问。
另一个好的编程习惯是确保只有智能合约的所有者或多名智能合约的所有者或授权人员才有权自行破坏合同。
假设还为合同指定了持续时间。 修饰符用于强制执行此智能合约的析构函数地址和持续时间。
区块链Dapps Coursera(第三周)设计改进_第8张图片
执行kill函数时会发生什么。如果满足修改人指定的条件,则smart contract代码将从区块链状态中删除。在我们的例子中,条件是指定的地址调用函数,并且指定的时间已经过去。存储在该智能合约地址中的剩余 gas 将转移到自毁 self-destruct 调用参数中指定的地址。智能合同本身由于其当前地址而无法访问。

记住,智能合约可能代表一项资产或一项业务。在资产的生命周期内,所有权可能会改变。它可能因资产的出售、捐赠或遗赠而改变。还有更多的所有权转移场景。
这个函数可以实现所有权的转移,但请确保您使用一个或多个修饰符来限定转移,以便执行适当的规则。
区块链Dapps Coursera(第三周)设计改进_第9张图片

我们正着手管理智能合同之间管理所有权和生命周期的关系。到目前为止,我们已经创建了一个智能合约。复杂的应用程序可能由许多智能合约组成,一个实例化另一个或继承其他合约。组织的符号或名称空间也有可能在需要应用的通用智能合约中定义。 导入命令可用于在智能合约中包括文件。在编译时,重要文件和当前智能合约之间建立关联,并根据这种关联生成字节码。这就引出了编程实践三。可组合性、专门化和泛化 Composability, specialization, and generalization 是面向对象的重要原则,这有助于为复杂问题设计智能合约解决方案。

如您将在后面的模块中看到的,这还提高了组织和参与者之间代码和标准的可重用性。 接下来,我们将探讨继承及其在基于智能合约的应用程序中的重要性。 例如,这里称为联邦法律的联邦法律可以是一个法律框架,可以很好地表示接口智能合约,让州和总部外办事处根据自己的意愿执行它们。 在这种情况下,StateLaws和FieldLaws也是智能合约,它们使用import语句关联。 这是工作中的继承。
区块链Dapps Coursera(第三周)设计改进_第10张图片

作为智能合约之间关系的子主题,可以创建库并将现有库导入到您的Solidity智能合约代码中。库 Libraries 是特殊的智能合约,没有以太币余额,没有 payable 函数,也没有要区块链中的存储状态。一个很好的例子是 Zeppelin 的 SafeMath.sol,它可以包含在您的智能合约中用于任何数学计算。import SafeMath.sol。许多库尚未创建。您可以肯定,将会出现许多特定于域的库。这是一个机会。您也可以为您的应用程序域创建有用的库。

总结:我们在本课中探讨了三个重要概念,即智能合约中数据的内存与存储属性,管理智能合约的生存期和所有权以及继承。生命周期和所有权是智能合约特有的,某些DApp开发人员可能会轻视其重要性。

阅读材料
Scaling Blockchain Computation and Storage by Daniel Larimer

测试题
区块链Dapps Coursera(第三周)设计改进_第11张图片
区块链Dapps Coursera(第三周)设计改进_第12张图片

事件处理 Event Handling

Event Handling (Part 1)

我们为什么需要 event ?回想一下,我们在第二课程中介绍了事件 event 。
1)event 对于推送通知以指示智能合约操作的完成(例如转移的执行)很有用。
2)event 对于智能合约的日志活动非常有用。在此角色中,event log 类似于 printf 或控制台日志。日志可以用来审核智能契约的功能。
3)event 支持 event 发送方和接收方之间的异步操作。
4)event 框架是轮询以检查请求是否已完成的有效替代方法。
区块链Dapps Coursera(第三周)设计改进_第13张图片

完成本课程后,您将能够说明如何使用事件记录日志并将智能合约的状态推送至应用程序,并说明在智能合约(即Coin智能合约)的设计中事件的用法。

您如何编程设置调用事件?通过名称和参数定义事件。
事件可以像函数一样参数化。例如,在coin.sol中,您将看到带有参数from,to 和 amount 的 event sent。您可以通过事件的名称和实际参数值来调用事件。 这将为其监听器推送或记录一个事件发生,例如,在coin.sol中,您将看到发送带有参数sender,receiver和amount的事件。
区块链Dapps Coursera(第三周)设计改进_第14张图片

您如何消费事件? 您为一个或多个事件设置了监听器,并使用或捕获事件通知,然后对其进行操作。
我们将使用 Coin de-application 应用程序说明事件。Coin 智能合约有两个数据项。第一个是 minter 或 owner 的地址。第二个是账户地址和硬币余额之间的映射(见上图第一个框)。请理解,这不是用于支付 gas point 的以太币。
发送的事件由三个参数定义。 在传输功能内完成传输后,将推送 push 或记录 log事件。 我们将在 truffle IDE 和 Metamask上使用 Coin Dapp。

Coin 有一个构造函数。 它具有 mint 函数,只有 minter 才能执行给给定地址发行新货币的操作。 您将必须在 metamask 帐户中注册一个帐户,或者在 minters 帐户中注册一个帐户。 最后一个函数是可以将货币从一个帐户转移到另一个帐户的 transfer 函数。 您必须是发送者的帐户,才能进行转移。

你如何处理这个事件?
设置事件处理程序的方法有很多。我们选择了 truffle 文档中建议的方法。这涉及在JavaScript应用程序 App.js 中对其进行处理。
这种方法使您可以方便地处理事件,并将JavaScript资产注入Web以显示事件通知。 如果您尚未这样做,现在可以从资源部分下载Coin.zip到您的工作区中。
将Coin.zip解压缩,cd 到 Coin 目录,在另一个终端执行 truffle develop 命令,truffle migrate --reset,设置好 metamask 去连接测试链,使用命令 npm run dev 运行测试。
区块链Dapps Coursera(第三周)设计改进_第15张图片区块链Dapps Coursera(第三周)设计改进_第16张图片

现在,转到设置metamask的Chrome浏览器。在浏览器链接中,输入localhost:3000。它应该打开Dapp的Coin界面,查看实际事件。

Event Handling (Part 2) (Coin Demo)

您可以使用 Coin 智能合约来演示事件日志记录。我已经从我们的资源中复制了coin.zip。让我解压缩它,这样就会创建所有的工件。 您可以在 contracts 中查看 Coin.sol 。有三个函数,包括Coin构造函数,Mint(仅由minter发行货币)和可以在任何帐户之间进行的转移的 transfer。 sent event 有三个属性,即发送者 sender,接收者 receiver 和金额 amount,您可以在此处看到定义的事件。

pragma solidity ^0.4.17;
contract Coin {
    // The keyword "public" makes those variables
    // readable from outside.
    address public minter;
    mapping (address => uint) public balances;

    // Events allow light clients to react on
    // changes efficiently.
    event Sent(address from, address to, uint amount);

    // This is the constructor whose code is
    // run only when the contract is created.
    function Coin() public {
        minter = msg.sender;
    }

    function mint(address receiver, uint amount) public {
        if (msg.sender != minter)
          revert();
        balances[receiver] += amount;
    }

    function transfer(address receiver, uint amount) public {
        if (balances[msg.sender] < amount)
          revert();
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Sent(msg.sender, receiver, amount);
    }
}

****本文中所有图片为视频截图,尚未实际操作,实际操作后补图。
让我们运行。 进行 truffle compile ,如果您愿意,您可以直接进行测试。 我也将对其进行测试,我们在此处放置了一些测试用例,以后您可以通过查看test.js进行检查。 truffle test,然后您可以看到测试,然后我将进行 truffle migrate --reset,npm run dev,然后就打开了界面。
区块链Dapps Coursera(第三周)设计改进_第17张图片
区块链Dapps Coursera(第三周)设计改进_第18张图片
区块链Dapps Coursera(第三周)设计改进_第19张图片
这将打开您所看到的界面。 这是 minter 的界面,它包括 check balance,mint coin 和 sent coin。 所有普通账户都有另一个界面,没有 mint coins。
区块链Dapps Coursera(第三周)设计改进_第20张图片
让我们回到Metamask界面,在地址栏输入 localhost:3000,进入普通账户的界面,
区块链Dapps Coursera(第三周)设计改进_第21张图片
在右上角的matamask图标里可以选择不同的账户,现在的界面是 Account 4,如果换到 Account 1,将是如下的样子。可以进行相应操作。
区块链Dapps Coursera(第三周)设计改进_第22张图片

阅读材料
Solidity Events Tutorial - Using Web3.js to Listen for Smart Contract Events
Calls, transactions, events, filters and topics
Technical Introduction to Events and Logs in Ethereum

测试题
区块链Dapps Coursera(第三周)设计改进_第23张图片
区块链Dapps Coursera(第三周)设计改进_第24张图片

Oraclize

回想一下智能合约在沙箱中运行。它不能调用外部函数或链接到外部资源。那么如何访问外部资源呢?
利用一种特殊的智能合约 Oraclize

完成本课程后,您将能够说明一种从智能合约访问外部资源的方法,并说明oraclize智能合约的工作方式。

为什么智能合约无法从外部访问资源
根据源代码,它可能会影响区块链的全球一致性 global consistency。区块链上操作的结果必须是确定性的。这些条件限制了智能合约在许多实际应用中的适用性,这些应用可能涉及从外部世界获取事实,数据和资产。 此外,数据必须在执行时获取,并且在部署合同时可能不可用。

让我们看一些例子。 某一天乞力马扎罗山的温度如何?这是普遍的事实,但是必须在特定的一天从真实的外部天气源获得。
第二个例子是纳斯达克市场上特定日期的股票价格数据。

oraclize概念解决了从智能合约中获取外部数据的问题

什么是oraclize?
当您查找oracle的含义时,Merriam-Webster 对 oracle的定义是权威或明智的表达或答案。此定义非常接近地定义了智能合约dApp开发中的正式服务规则。
Oraclize被描述为Web资源,API和URL与智能合约之间的数据载体。
区块链Dapps Coursera(第三周)设计改进_第25张图片
当然,oraclize在区块链协议之外。但是,它是dApp的有用组成部分,可促进某些智能合约运行所需的现实情况的可用性。

我们如何使用oraclize服务?
UsingOraclize是一个智能合约,它提供最少的查询功能来访问外部资源。 它不仅获取数据,而且还可以通过调用智能合约提供有关源的证明和身份验证。
区块链Dapps Coursera(第三周)设计改进_第26张图片
由于访问数据和验证可能需要一些时间,因此通过回调函数返回请求的数据。 

 以下是使用Oraclize和外部数据源的有关智能合约的简单类图
区块链Dapps Coursera(第三周)设计改进_第27张图片

现在,让我们看一下时序图,以遵循各种功能的执行时间表。 通过智能合约,可以部署平均冬季温度。
​​​​​​​它调用 fetchData 函数。 依次使用数据源的URL进行 oraclize_query。由于获取数据可能会花费一些时间,因此提供了一个回调函数 call back,以便可以在获取所需数据时调用它。
UsingOraclize访问外部数据源,进行身份验证并将带有证明的数据发送到原始智能合约。
区块链Dapps Coursera(第三周)设计改进_第28张图片

如何使用 usingOraclize?
1)您需要使用import语句使用Oraclize智能合约进行导入。
2)合约 “AverageWinter Temperature” 继承自 usingOraclize。 合约 AverageWinter Temperature正在使用 Oraclize。
在这里,AverageWinter Temperature是使用Oraclize继承并使用其功能来访问外部资源。
区块链Dapps Coursera(第三周)设计改进_第29张图片

使用Oraclize让您编写的智能合约继承。 它提供了诸如 oraclize query 之类的功能,并允许您指定数据源地址 data source address。 您在查询中指定外部数据源地址。此外,您可能还具有验证所获取数据的证据和真实性的方法。

总结:我们了解了一些可以改进Dapp基本设计的最佳实践。
1)数据结构级别 data structure level,即内存 memory 与存储 storage。 这有助于最小化Dapp在区块链上的占用空间。
2)第二个是关于事件日志记录 event logging,它对于Dapp客户端的异步操作是有用的,从而提高了效率。
3)第三个是关于从外部来源访问数据和事实,这对于许多实际的Dapps都是必不可少的。

阅读材料
Getting data from the internet with Oraclize
Oraclize Documentation

测试题
区块链Dapps Coursera(第三周)设计改进_第30张图片

 

你可能感兴趣的:(区块链学习笔记)