div#pop_ad { opacity: 0; }
AD
首页 > 数字货币 > 正文

区块链-智能合约工作流初探、再探、初悟

[2021-01-29 07:38:13] 来源: 编辑:wangjia 点击量:
评论 点击收藏
导读: No.10 智能合约工作流初探上一篇讲到Remix,接下来我们具体看看如何编译、部署、测试智能合约。编译 打开实时编译auto compile,无需多余的操作,注意下面提示框即可,红色存在错误,绿色



区块链-智能合约工作流初探、再探、初悟

No.10 智能合约工作流初探



上一篇讲到Remix,接下来我们具体看看如何编译、部署、测试智能合约。

编译 打开实时编译auto compile,无需多余的操作,注意下面提示框即可,红色存在错误,绿色代表无语法错误。

Remix已经识别到代码中智能合约Car。



区块链-智能合约工作流初探、再探、初悟



切换到Run选项卡,分为4个小区域:



区块链-智能合约工作流初探、再探、初悟



为了部署我们自己的智能合约,必要操作步骤如下:

1、在区域 1,运行环境 Environment 中选择 Javascript VM,即把合约部署到运行在浏览器内存中的测试网络,既然是运行在浏览器内存中的网络,页面刷新的话数据将会被重置,但是如果我们部署在主域 Rinkeby 测试网络上,数据就不会丢失;

2、在区域 2,initialBrand 的输入框里面填入 "AUDI",注意填入的内容必须包含两边的引号,没有引号会导致错误,这是很多新同学会碰到的问题,实际上你可以理解为参数必须是 JSON.stringify 后的结果; 在区域 2,单击

"Create",部署新的智能合约实例;



区块链-智能合约工作流初探、再探、初悟



合约部署完成之后,在最下面能看到新的合约账户,账户下面有 3 个按钮,每个按钮代表 1 个可以调用的合约函数,如 getBrand,如果按钮旁边有输入框,表示调用该函数的时候需要输入参数,如 setBrand。我们直接点击 brand 或者 getBrand 按钮,会看到按钮右边立即显示了部署合约时设定的 AUDI,如果不小心点击了 setBrand,却没有在点击之前在其右边的输入框里面填入任何内容,恭喜你,智能合约中的 brand 属性现在已经被置空了,这也是 Remix 的一个大坑:不做参数校验,并且即使失败也是悄悄的失败。如何正确更新 brand 属性的值呢?需要先在 setBrand 右侧的输入框里填入 "BMW",同样包含两边的引号,然后单击 setBrand 按钮。

可能细心的同学已经注意到了,我们合约里面没有声明 brand 方法,但部署后的合约里面有,这就是 Solidity 为可公共访问的存储型变量生成的 getter 方法,实际上我们源代码中的 getBrand 方法可以直接删掉的。

纸上得来终觉浅,学到不如做到!期望读到这里的你已经把 Car 智能合约的代码输入到 Remix,并且部署自己的合约实例,测试了合约函数,有没有发现什么问题?下章让我们深入聊聊智能合约相关的各种问题。

No.11 智能合约工作流再探


合约部署(Create)和合约实例(Contract Instance)里面有太多的细节需要扒清楚,才能达到知其然且知其所以然的理解深度。比如下面几个问题对我们的理解非常关键:

1、智能合约部署的时候到底发生了什么事情?发送了什么数据?

2、部署合约的时候到底用的哪个账户?消耗的汽油从哪里来?

3、合约账户的形式是什么样的?和普通账户有没有区别?

4、新创建合约实例上的 3 个方法对应的按钮,为啥 setBrand 是红色而 getBrand 和 brand 是蓝色的?两种到底有啥区别?对后续的 DApp 开发有什么影响?

5、前面章节中我们给 Metamask 账户充值的时候讲到以太坊单笔交易确认时间平均在 15s 左右,为什么 Remix 测试时候那么快?几乎是马上就能有结果?

6、如果合约源代码修改了,我们能否直接在老的合约实例上进行测试?如果不能是为什么?要测试新合约该怎么做?

7、合约编译的时候虽然没有报红色的错误,但是报了蓝色的 Warning,那是什么原因?该怎么修复? 只要把上面这些问题逐个搞明白,我们在智能合约部署、合约函数调用等方面就能毕业了,哈哈!

合约部署的本质

前面提到合约部署实际上是发起了 1 笔交易,交易的接收者为空,以太坊将接收者为空的交易默认为是合约实例创建请求,这类交易中会携带当前部署合约的机器码(ByteCode),部署成功的话会返回新建的合约账户,合约部署本身需要消耗 Gas,这个费用是发起者支付的。合约部署的交易细节再 Remix 上通过调试日志可以一览无余,打开 Remix 的调试日志区域,通过点击合约创建日志右上角的 Details 按钮,展开交易细节,如下图:



区块链-智能合约工作流初探、再探、初悟



其中 contractAddress 是交易的返回结果,而不是携带在交易中的信息。此外,可以看到交易中携带的合约机器码是十六进制串,如果想查看某个合约编译后的机器码,可以直接在 Compile 目录下点击 Details 按钮,如下图:



区块链-智能合约工作流初探、再探、初悟



BYCODE是否相同?

汽油从哪里来?

细心的同学可能观察到了,上面合约部署交易中的 from 字段 0xca35b7d915458ef540ade6068dfe2f44e8fa733c 跟右侧调试区域 Javascript VM 下面出现的 Account 列表中的第一个账户完全相同(核对前后各 5 位即可),余额比其他账户少一点点。



区块链-智能合约工作流初探、再探、初悟



合约账户的本质

合约部署的直观结果是我们得到了一个账户,但是我们仅仅有这个账户的地址,而没有账户的公钥、私钥,这就是合约定义:contract instance is an account controlled by code 的准确含义,后续和合约的交互也只能通过代码,即智能合约的函数调用。

Remix 带来的幻觉

在 Remix 上部署、测试智能合约,不论是 call 还是 transaction,速度都非常快,这是因为测试时以太坊网络运行在内存中,并且是单节点,速度自然很快,但是缺陷是每次页面加载,这个测试网络中的合约实例、合约中的数据都会丢失,网络中的账户及余额也会重建。

然而实际的以太坊网络,不论是测试网络还是主网,都不会这么快,原因在前面有讲,在分布式网络上达成共识确实是个很复杂的过程,尤其是对于目前使用 POW 共识算法的以太坊来说。

如何重新发布?

前端工程师修改页面源代码后需要刷新浏览器,才能看到最新的页面效果,如果智能合约的源代码被修改,我们同样需要重新部署智能合约的示例,并测试这个全新的合约实例。与前端页面开发不同的是,刷新浏览器之后,老的页面的各种样式、DOM接口、应用状态都被销毁了,而以太坊上老的合约实例是不会被销毁的,即使部署了新的版本,如果你愿意也能和老版本继续交互。

Solidity 其实和 JS 区别很大

到目前为止,可能我们并没有看出 Solidity 和 JS 有太大差别,但实际上差别是非常大的,得从 Remix 里 Compile 功能给出的蓝色提示说起,如果双击蓝色 Warning 提示,Remix 会跳转到 Analysis 选项卡,滚到页面底部我们能看到 Warning 的详细说明,如下图:



区块链-智能合约工作流初探、再探、初悟



Car 合约自动生成的 brand 函数可能会消耗无限的汽油,这是在智能合约设计时需要避免的,因为智能合约中的任何代码都是需要消耗汽油的,如果不加限制,很容易出现因为汽油不够而操作被回滚、或调用失败的情况。

具体到我们的例子,brand 属性为字符串,在静态类型语言中字符串本质是动态长度的字节数组(dynamically-sized byte array),也就是说我们的 brand 属性是可能是非常长的字符数组,如果长度超过某个临界值,就会消耗超出预期的汽油,具体到我们的例子,只需要把 brand 的类型从 string 设置为 bytes32 即可。

这里就引申出一个问题,Solidity 中的变量类型和 Javascript 差别就比较大,虽然都可划分为基本数据类型和引用数据类型两大类。

只谈区块链不谈币--No.12 智能合约工作流初悟


调用合约函数时到底发生了什么?

上面提到 Remix 渲染出来的智能合约函数被用颜色标记成了两类,如果鼠标在两类函数的按钮上停留 2s 钟,相信你会觉察到两者的区别(浏览器弹出的 title 提示),如下面两张图:

setBrand 被标记为红色,调用它实际发起的是 transaction,任何交易都是全异步的。



区块链-智能合约工作流初探、再探、初悟



而 getBrand 被标记为蓝色,调用它就是简单的函数调用:call。



区块链-智能合约工作流初探、再探、初悟



智能合约中的函数要么是 transaction 类型,要么是 call 类型,两种类型函数的本质都是接口请求,但是又存在很大的区别,对比如下表:



区块链-智能合约工作流初探、再探、初悟



对于前端工程师来说,如果用同步、异步函数来类比则很好理解(严格来说这个类比不是非常恰当): 合约中的纯粹函数调用相当于是同步的,而通过交易去调用的函数相当于是异步的;

通常我们不指望异步函数马上返回结果,除非给他传入了回调,这也就预示着智能合约中会修改合约数据的函数即使声明了返回值,也是无效的(让人不解的是 Remix 也不会因为这个报错),因为调用的时候只会返回交易哈希。

#热议区块链#

至此,第一部分 教学篇完结

后续计划 更新第二部分 进阶篇

NO.13 自建智能合约 Prepare

NO.14 编写智能合约 Compile

NO.15 部署智能合约 Deploy

NO.16 查看智能合约 Etherscan

NO.17 测试智能合约 Mocha

添加新手交流群:币种分析、每日早晚盘分析

添加助理微信,一对一亲自指导:YoYo8abc

查看更多:

为您推荐