DAPP 开发实践教程(一):解决缺少 Truffle 相关导入库文件的问题

2024-11-23 17:12:01

在之前的教程《随性开发DAPP实用教程(一)搭建好用的开发环境》中,我们根据官方提供的例子进行了初步的开发实践和代码分析。我们甚至已经能够根据合约编写测试代码并检查结果,一切看起来都不错吗?

不过,值得注意的是,我们使用“.cmd test”来执行.js文件中的代码。如果我们直接使用或者在浏览器中打开它,我们会立即收到堆积如山的错误提示。显然,这是由于JS程序代码中缺少相关的导入库文件,导致大量方法找不到。

显然,作为一个完整的、可以向公众发布的DAPP,我们希望它能够在浏览器中与前端接口的代码结合起来,然后等待调用后端智能合约接口的机会连接私有或公共区块链系统。仅仅用于测试的代码是完全无法满足这样的要求的。

它满足了我们对前端用户界面的迫切需求,也通过它自己的例子。我们只需按照之前的下载方法,在控制台输入:

#mkdir

#光盘

# .cmd 拆箱

这次等待的时间会更长。其实这是因为前端代码和合约之间的通信需要大量的依赖库。下载的目录中有很多新文件,这些文件与合约的编写和发布没有直接关系。这里的子目录存放了所有需要使用的第三方依赖库,包括Babel,它提供了最新的JS语言特性、代码检查工具以及最重要的以太坊专用通信接口Web3。 app子目录存储Web界面代码、CSS样式和JS脚本。项目根目录下新增的.json文件主要用于npm查找和更新依赖库,以及查找必要的模块。

接下来的工作与上面提到的没有什么不同。打开测试链后,仍然通过控制台顺序执行,即在目录中:

#.cmd

#.cmd

事实上,项目中涉及的合约代码并没有什么区别。它只是演示了如何向这个非常原始的代币合约案例添加图形前端。不过,这也正好让我们有时间更详细地研究智能合约的发布和使用过程,进行反思,准备从头开始编写自己的DAPP程序。

现在,我们仍然可以通过.cmd测试来进行快速的合约功能测试,但我们已经不满足于此了。我们需要的是在浏览器端看到我们的结果。然而,简单地双击app/index.html不会有任何效果:浏览器对本地运行的JS脚本有各种安全限制。例如无法读取外部JSON脚本,相关代码可能无法正常执行;另外,我们还要考虑加载的模块数量。

我们首先需要确认前端代码中设置了正确的私链地址和端口。从上一篇文章我们已经知道默认地址是127.0.0.1:7545。打开app//app.js,找到设置地址和端口的代码段。并修改为正确的值如图:

这时我们还可以看看app.js中的其他代码段来了解智能合约函数()和()的调用方法。简单来说,和上一篇教程中的测试JS代码几乎是一样的,这对于我们这些准备自己写前端代码的人来说,无疑是一个好消息。

保存退出后,一切似乎仍然毫无头绪。幸运的是,我们有强大的npm。在控制台输入:

# npm 运行开发

此时会启动开发者模式,自动建立本地服务器并调用index.html显示前端界面。

根据控制台输出的提示,在浏览器(我用的就是)中输入:8080,看看会发生什么情况?

太棒了。现在从用户列表中选择一个地址,将该用户的地址粘贴到网页上,然后与他共享当前持有的一些代币。

在交易记录中可以找到这条最新的交易,我们可以从TX DATA中找到刚刚输入的用户地址,以及发送的金额(1000的十六进制是3e8)。

然而,携带如此庞大的依赖库毕竟是一个巨大的负担。大多数API与当前项目没有直接关系,甚至包括一些对本项目完全无用的案例和文档代码;我们正在构建自己的网络应用程序。有时候,你肯定不想使用 npm 来启动服务。但我们还有另一个命令要执行。按Ctrl+C退出当前服务,继续在控制台输入:

# npm 运行构建

进入build子目录后,我们可以找到新生成的index.html和app.js文件。与前一个相比,后者的大小相当可观(从 4KB 到 1.34MB)。显然是多个依赖库打包合并后的。结果。

非常令人兴奋,对吧?现在我们将构建目录中的文件(本项目中只有HTML和JS文件,并且不需要包含编译合约时生成的子目录)复制到新位置,并启用任何Web服务器构建工具(大多是简单的方法)是在新位置执行 .exe -m(如果已安装):

是的,因为它仍然在运行,并且私链仍然存在,所以当前用户(默认情况下始终是该用户)持有的代币仍然是 9,000。尝试将令牌发送给另一个用户后:

一切顺利!而如果直接双击HTML文件在浏览器中打开,也可以看到正确的调用结果。这意味着我们以后会有更多的方式调用后端合约代码,比如直接用C/C++调用这里的JS代码或者通过嵌入式开发库调用Unity游戏引擎(即地址为) (当然,这不是一个非常优雅的解决方案,但对于初学者来说足够简单)。也许我们会在后面的系列教程中尝试这个。

2. 合约发布脚本及流程

现在我们来关注一个之前被忽略的问题:“.cmd”命令到底是做什么的?

顾名思义,将编译好的智能合约“移植”(或更准确地说,发布)到区块链的过程。这个过程也需要控制得相对简单。

发布过程可以人为地分为多个阶段。每个阶段都由单独的.js脚本控制,这些脚本保存在项目的子目录中。在我们当前使用的 / 示例中,该目录下只有两个文件,分别是:

.js:负责在.sol中发布智能合约。该合约是自动生成的,有自己内置的接口标准,通常不需要用户修改。主要用于管理已发布合约的所有历史数据。

.js:负责发布用户编写的智能合约。在本项目中,它们保存在两个文件中:.sol(合约代码)和.sol(辅助功能代码),后者被前者引用。

这种类似于“序列号_描述.js”的文件命名方式并不是必需的,但它主要起到两个作用:一是可读性。用户可以从文件名中轻松了解发布合约的各个阶段。该怎么办;二是建立正确的执行顺序。发布过程中,每个阶段的脚本都会按照文件名的顺序执行。以数字序列开始无疑可以确保正确的执行顺序。

另外,我们每次执行“.cmd”时,都会自动判断用户代码是否发生变化以及合约上次发布时的最后一个阶段在哪里。然后查找用户是否在目录中添加了新的阶段脚本,并且只运行新的脚本。因此,如果我们在控制台中重复输入该命令(在此过程中没有对合约代码和发布脚本进行任何更改),则会第二次给出“最新”(无需更改)的提示。

这对于合同发布过程具有很大的实用价值。毕竟,以太坊区块链上的所有“写”操作都需要相应的资源(ETH)。如果我们因为错误的操作而重复签发一模一样的合约,我们自然会白白失去我们的“以太”。发布过程可以保证只有修改或新增的合约才发布到链上,避免财产损失,也避免链上积累大量无用数据。

请注意,我们可以使用以下命令强制重新发布所有合约:

# .cmd --重置

对于 ,使用发布合约意味着支付 ETH 作为价格(并且区块链必须在此之前可用);但是,它可以随时执行,并且所有操作只影响本地磁盘。

打开.js文件,里面的内容基本一目了然:

var = .("./.sol"); //获取接口对象

var = .("./.sol"); //获取接口对象

。 = () { //固定格式,定义合约发布函数

.(); //发布到区块链

。关联(, ); //链接到

.(); //发布到区块链

};

通过阅读上一篇文章,我们已经知道该函数是提供辅助函数功能(虽然只有一个()),并且在.sol的合约代码中也作为导入库使用。这与C/C++语言中使用#包含函数声明非常相似;以此类推,这里我们使用.link()来链接行为,可以类比C/C++中的Link。只有在此之后才能生成并发布正确的合约结果。

合约涉及到的所有接口对象都是通过.()获取的。值得注意的是,由于本项目中每个.sol文件中只定义了一个接口,因此()的参数可以直接传递给目录下的文件。姓名。如果.sol中定义了多个接口,例如.sol中定义了两个接口对象 和 ,则需要在发布脚本中使用以下语句分别获取这两个对象:

var = .("");

var = .("");

有关发布脚本和流程的更多信息,可以参考官方入门文档:

3.通过网站发布DAPP程序

我们修改了上一章前端接口对应的app.js文件内容,正确对应区块链的服务器地址和端口号。现在我们再次打开这个文件(对于项目来说,它位于app//目录下),简单了解一下它的作用。

(1)文件开头首先导入必要的依赖库(web3和-)以及编译好的合约文件,建立唯一的抽象层接口。

(2)然后我们定义一个JS级别的App接口,主要包含四个成员函数,分别是:

App.start():设置区块链的web3接口为抽象层,从web3.eth获取用户列表,设置交易的发起用户(本项目中始终设置为[0])并刷新用户他持有代币数量。

App.():设置HTML界面上的日志输出内容。

App.():刷新当前用户持有代币总量及界面显示。这里,实例对象触发()方法,实现JS前端对合约接口的调用。

App.():发送一定数量的代币到接口中给定的用户地址。这里,实例对象触发()方法,实现JS前端对合约接口的调用(HTML文件中也有相应的代码)。

(3) 在.('load')包含的代码段中,我们尝试从预设的区块链服务器地址和端口获取web3接口对象。因为这段代码是在网页加载时自动执行的,所以可以保证HTML页面加载后会获取到该对象,然后执行App.start()来初始化合约调用的相关接口。

事实上,它甚至提供了一个浏览器端工具,可以通过插件直接加载到浏览器中,帮助编译、发布和审核合约,以及连接区块链服务。这种情况下,不需要在app.js中设置区块链服务器的地址和端口。有关此工具的说明,请参阅:

并且.('load')也会优先尝试直接获取web3对象。如果失败,则会通过JS文件中提供的地址进行连接。当然,后续合约接口调用会保持一致。

现在,我们将尝试将这个项目发布到一个简单的网站上,以便其他客户端(例如手机)也可以访问该界面并交互地完成智能合约查询和交易操作。我们可以通过控制台简单查询我们主机的IP地址(作者是192.168.0.101)。

将该IP地址填入项目根目录下的.js文件(用于配置合约的发布脚本)、app//app.js文件(配置前端访问)、服务器设置页面:

选择“保存并重启”(Save & )后,这里有一点需要注意:它是一个测试专用的私链生成和维护工具。一旦关闭或重启,链上的所有区块,以及该区块上的合约也将被清除和重置。另外,我们修改了多个合约相关的脚本文件,所以这里最好重新执行“编译-发布-生成前端页面”指令流程:

#.cmd

#.cmd

# npm 运行构建

之后,我们可以进入build子目录,或者将新生成的index.html和app.js复制到一个新目录,并建立一个基本服务器(例如通过):

#.exe -m 8000

在浏览器上打开:8000看看是否能正确显示代币总量,然后发送一些代币到任意用户地址看看交易能否成功完成?

同时,我们还可以通过其他客户端(例如手机浏览器)进入同一网站,刷新并观察代币总量的变化,或者进行更多的交易操作。

至此,虽然还很原始,但我们已经有了一个可以正常运行的智能合约后端,一个基于 HTML+JS 的前端界面,并可以通过多个客户端访问它们。接下来,是时候创建一些您自己的内容了。

标签: DAPP
首页
欧意注册
欧意下载
联系