如何在Ubuntu上通过Docker安装Solidity编译器?

122 阅读7分钟

在这篇文章中,我们继续建立在上一个主题--Solidity编译器的安装。 在这篇文章中,我们将通过Docker来安装和使用Solidity编译器。

我们的目标是更加熟悉这种方法的可能性,以及了解 "运行该节目 "的技术。这些知识和经验将使我们能够认识到在未来选择任何一种方法背后的原因,这取决于我们项目的实际需要。

什么是Docker?

在我们详细介绍solc 的Docker安装之前,首先让我们介绍一下什么是Docker。

💡 Docker是一个开发、运输和运行应用程序的开放平台......Docker提供了在被称为容器的松散隔离环境中打包和运行应用程序的能力......容器是轻量级的,包含运行应用程序所需的一切,所以你不需要依赖主机上当前安装的东西。

在描述中,有一些部分我特意省略了(用符号...隔开),因为它们对我们理解这项技术并不重要。

现在,我们来剖析一下Docker的描述:我们感兴趣的关键词是 平台, 隔离环境,以及 容器.接下来,让我们快速深入了解每一个关键词

平台

一个平台是一个支持特定功能或目标的软件框架。

Docker支持的目标是使一个软件(应用程序、服务等)能够正确地运行,无论目标环境如何。

对我们来说,这意味着运行Solidity编译器,即向它输入源代码,并以.abi.bin 文件的形式产生输出字节码。

隔离的环境

提到隔离环境,我们就会想起之前学过的虚拟化的概念,也就是说,Docker通过提供软件库、网络访问、远程服务和其他依赖性等形式的资源,使我们的软件能够按照预期运行。

容器

Docker通过将资源安排在一个称为容器的包中,确保提供这些资源而无需额外干预。容器以我们最常下载和运行的图像开始其生命周期。

我们也可以创建一个Docker镜像,但那是另一个故事。

运行一个镜像会创建一个实时实例,即一个容器。在使用之前,Docker镜像必须被准备好,这意味着有人应该安装和配置软件运行所需的所有资源。

Docker镜像的准备属于*DevOps*的范畴,即开发和运营。

💡 "DevOps工程师管理软件开发的操作,实施工程工具和软件开发过程的知识,以简化软件的更新和创建。"

通过Docker使用Solidity编译器

现在我们已经介绍了Docker的概况,我们继续通过Docker安装Solidity编译器。

首先,我们必须通过同时检查Docker版本来检查Docker是否存在于我们的系统中。

$ docker version
bash: /usr/bin/docker: No such file or directory

正如我们的检查所示,在使用Docker之前,我们必须在系统上安装它。通过Ubuntu资源库的安装过程由几个步骤组成(https://docs.docker.com/engine/install/ubuntu/):

第1步:更新apt软件包索引

$ sudo apt update
…
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.

第2步:安装软件包

安装额外的软件包;我们需要这些软件包来使安装过程通过安全的HTTPS连接访问存储库(注意多行命令的反斜杠符号\ )。

$ sudo apt install \
ca-certificates \
curl gnupg lsb-release
...
The following additional packages will be installed:
  gnupg-l10n gnupg-utils gpg-wks-server
Suggested packages:
  parcimonie xloadimage
The following NEW packages will be installed:
  ca-certificates curl gnupg gnupg-l10n gnupg-utils gpg-wks-server lsb-release
...
Do you want to continue? [Y/n] y
...

第3步:添加Docker GPG密钥

添加Docker的官方GPG密钥。

$ sudo mkdir \
-p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg – dearmor -o /etc/apt/keyrings/docker.gpg

ℹ 信息"GPG,即GNU Privacy Guard,是一种公钥密码学的实现。这允许各方之间安全地传输信息,并可用于验证信息的来源是否真实。"

第4步:设置版本库

通过写到docker.list 文件来设置存储库。

echo 命令评估$( ) 内的文本,用命令输出(在括号内)填充它,并通过 stdin 发送给具有 root 权限的系统工具sudo tee ,后者反过来覆盖docker.list 文件,并通过重定向到/dev/null 省略输出。

$ echo \
"deb [arch=$(dpkg – print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee \
/etc/apt/sources.list.d/docker.list > /dev/null

ℹ 信息。错误添加的软件库可以在Ubuntu 20.04中通过选择性地删除 目录中的软件库来删除。/etc/apt/sources.list.d/

第5步:更新apt软件包索引

更新apt软件包索引(再一次)。

$ sudo apt update
...
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.

第6步:安装Docker

安装Docker(最新的稳定版本)和它的组件。

$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  docker-ce-rootless-extras docker-scan-plugin pigz slirp4netns
Suggested packages:
  aufs-tools cgroupfs-mount | cgroup-lite
The following NEW packages will be installed:
  containerd.io docker-ce docker-ce-cli docker-ce-rootless-extras docker-compose-plugin docker-scan-plugin pigz slirp4netns
0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
Need to get 108 MB of archives.
After this operation, 449 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
...

让我们再一次检查一下Docker的版本。

$ docker version
Client: Docker Engine - Community
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        100c701
 Built:             Mon Jun  6 23:02:57 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.11
  Git commit:       a89b842
  Built:            Mon Jun  6 23:01:03 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.7
  GitCommit:        0197261a30bf81f1ee8e6a4dd2dea0ef95d67ccb
 runc:
  Version:          1.1.3
  GitCommit:        v1.1.3-0-g6724737
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

现在我们确定我们的Docker安装已经完成,而且我们的Docker引擎版本是20.20.17 (在写这篇文章的时候)。下一步是获得带有Solidity编译器的Docker镜像。

Docker镜像是由其发布组织镜像名称(简称image)和标签,即使其独一无二的标签来识别的。一般来说,我们可以通过引用一个Docker镜像的organization/image:tag 标记来下载它。

我们将下载一个Solidity编译器的Docker镜像,通过指定其标记为ethereum/solc:stable ,表示稳定版本,而ethereum/solc:nightly ,表示边缘的、潜在的不稳定版本。

我们也可以通过将一个标记设置为特定的版本来指定Solidity编译器的不同版本,例如:ethereum/solc:0.5.4

我们将用一个Docker命令做三件事:我们将下载镜像,从镜像中实例化(运行)一个容器,并打印容器的用法(flag - help)。

docker run ethereum/solc:stable – help

当然,我们想编译我们的 Solidity 文件,所以我们要做三个准备(第一第二第三)。

首先。创建一个包含我们Solidity源代码的本地目录(我将使用Remix合约文件夹中的1_Storage.sol ,方法是创建一个空文件并将内容粘贴到其中)。

$ mkdir ~/solidity_src/ && cd ~/solidity_src/
$ touch 1_Storage.sol

第二:你可以写你自己的合同用于测试,或者直接用你最喜欢的文本编辑器打开1_Storage.sol ,然后把Remix中的1_Storage.sol 例子的内容粘贴进去。

第三:运行一个Docker容器(我们已经有了镜像,所以下载程序将被跳过);命令标志-v ,将我们的本地~/solidity_src 目录挂载到容器的路径/sources ,路径ethereum/solc:stable 选择Docker镜像来运行一个容器,命令标志-o 设置编译文件的输出位置,--abi--bin 激活.abi.bin 两个文件的生成,路径/sources/1_Storage.sol 选择编译的源文件。

$ docker run -v ~/solidity_src:/sources ethereum/solc:stable -o /sources/output – abi – bin /sources/1_Storage.sol
Compiler run successful. Artifact(s) can be found in directory "/sources/output".

当检查我们的solidity_src 目录时,我们会发现一个新的目录输出,由Solidity编译器创建,包含.abi.bin 两个文件。

Docker也使我们能够使用标准的JSON接口,在使用编译器与工具链时,这是一种推荐的方法。如果JSON输入是自成一体的,这个接口不需要挂载目录,换句话说,所有的代码都已经包含在源文件中,没有对外部的、导入的文件的引用。

docker run ethereum/solc:stable – standard-json < input.json > output.json

由于我们还没有做任何使用JSON接口的例子,我们将暂停这种方法,直到以后。

总结

这篇文章向我们介绍了一种叫做Docker的支持Solidity的技术。

当然,我们主要关注的是由SolidityEthereum区块链技术等组成的生态系统,但我认识到有机会绕道而行,带领我们了解通过Docker平台设置和使用Solidity编译器的过程。因此,虽然最初没有计划,但我们也获得了一些DevOps技能

在第一章,也是唯一的一章(是的,我也有点吃惊),我们通过了解Docker是什么,设置了采矿收费。然后,我们通过发现如何在Ubuntu Linux上安装Docker(以及延伸到其他一些操作系统),吹开了一大块石头。我相信这篇文章会被证明是有用的,并且在Ubuntu Linux上为Solidity设置开发环境方面提供了多种提示和技巧。除此之外,而且就我个人而言,每当我学习一个特定的主题时,获得二次知识总是很有用的,我相信你也会有同样的经历。