# 以太坊Solidity编程语言开发框架

By [paedy](https://paragraph.com/@paedy) · 2021-11-20

---

Truffle是一个世界级的开发环境，测试框架，以太坊的资源管理通道，致力于让以太坊上的开发变得简单，Truffle有以下：

内置的智能合约编译，链接，部署和二进制文件的管理。 快速开发下的自动合约测试。 脚本化的，可扩展的部署与发布框架。 部署到不管多少的公网或私网的网络环境管理功能 使用EthPM&NPM提供的包管理，使用ERC190标准。 与合约直接通信的直接交互控制台（写完合约就可以命令行里验证了）。 可配的构建流程，支持紧密集成。 在Truffle环境里支持执行外部的脚本。 Truffle是最流行的开发框架，使命是让开发更容易 安装方式：

$ npm install -g truffle 环境要求 NodeJS 5.0+ Windows，Linux，或Mac OS X Truffle需要以太坊客户端，需要支持标准的JSON RPC API。

1.  Truffle客户端 原文地址：[http://truffleframework.com/docs/getting\_started/client](http://truffleframework.com/docs/getting_started/client)
    

有许多的以太坊客户端可以选择。我们推荐在开发和部署时使用不同客户端。

适用开发的客户端 EtherumJS TestRPC 当开发基于Truffle的应用时，我们推荐使用EthereumJS TestRPC。它是一个完整的在内存中的区块链仅仅存在于你开发的设备上。它在执行交易时是实时返回，而不等待默认的出块时间，这样你可以快速验证你新写的代码，当出现错误时，也能即时反馈给你。它同时还是一个支持自动化测试的功能强大的客户端。Truffle充分利用它的特性，能将测试运行时间提速近90%。

适用正式发布的客户端 Geth (go-ethereum) WebThree(cpp-ethereum) More 对此有许多官方和非官方的以太坊客户端可供选择。最好使用TestRPC客户端充分测试后，再使用这些客户端。这些是完整的客户端实现，包括挖矿，网络，块及交易的处理，Truffle可以在不需要额外配置的情况下发布到这些客户端。

当发布到私有网络中 私人网络中使用了相同的技术，但却有不同的配置。所以你可以将上面提及的客户端来运行一个私有的网络，部署到这样的网络也是使用同样的方式。

1.  创建一个工程 原文地址：[http://truffleframework.com/docs/getting\_started/project](http://truffleframework.com/docs/getting_started/project)
    

创建工程目录 首先创建一个工程目录。你可以使用你喜欢的文件浏览器或使用下面的命令在命令行创建一个目录：

$ mkdir myproject 初始化你的工程 接下来，通过下面的命令初始化一个Truffle工程：

$ truffle Truffle v3.4.11 - a development framework for Ethereum $ cd myproject $ truffle init 完成后，你将拥有如下目录：

app/ - 你的应用文件运行的默认目录。这里面包括推荐的javascript文件和css样式文件目录，但你可以完全决定如何使用这些目录。 contract/ - Truffle默认的合约文件存放地址。 migrations/ - 存放发布脚本文件 test/ - 用来测试应用和合约的测试文件 truffle.js - Truffle的配置文件 默认工程：METACOIN truffle init会默认创建一个构建在以太坊内的代币demo应用。我们可以使用这个工程来进行快速的学习，或者你也可以删除这些文件来创建一个你自己的工程。

1.  编译合约 原文地址：[http://truffleframework.com/docs/getting\_started/compile](http://truffleframework.com/docs/getting_started/compile)
    

合约位置 所有你的合约应该位于./contracts目录。默认我们提供了一个合约文件，一个库文件，均以.sol结尾作为示例。尽管库文件有一定的特殊性，但为简单起见，当前均称之为合约。

命令 要编译您的合约，使用：

truffle compile Truffle仅默认编译自上次编译后被修改过的文件，来减少不必要的编译。如果你想编译全部文件，可以使用--compile-all选项。

truffle compile --compile-all 约定 Truffle需要定义的合约名称和文件名准确匹配。举例来说，如果文件名为MyContract.sol，那么合约文件须为如下两者之一：

contract MyContract { ... } // or library MyContract { ... } 这种匹配是区分大小写的，也就是说大小写也要一致。推荐大写每一个开头字母，如上述代码定义。

依赖 你可以通过使用import来声明依赖。Truffle将会按正确顺序依次编译合约，并在需要的时候自动关联库。

编译目录 编译的输出位于./build/contracts目录。如果目录不存在会自动创建。这些编译文件对于Truffle框架能否正常工作至关重要。你不应该在正常的编译或发布以外手动修改这些文件。

1.  移植 原文地址：[http://truffleframework.com/docs/getting\_started/migrations](http://truffleframework.com/docs/getting_started/migrations)
    

移植是由一些Javascript文件组成来协助发布到以太坊网络。主要目的是用来缓存你的发布任务，它的存在基于你的发布需求会改变的前提。当你的工程发生了重要的改变，你将创建新的移植脚本来将这些变化带到区块链上。之前运行移植的历史记录通过一个特殊的Migrations合约来记录到链上，下面有详细说明。

命令 执行移植，使用下述命令：

truffle migrate 这个命令会执行所有的位于migrations目录内的移植脚本。如果你之前的移植是成功执行的。truffle migrate仅会执行新创建的移植。如果没有新的移植脚本，这个命令不同执行任何操作。可以使用选项--reset来从头执行移植脚本。

移植脚本文件 一个样例文件如下：

文件名：4\_example\_migration.js

module.exports = function(deployer) { // deployment steps deployer.deploy(MyContract); }; 需要注意的是文件名以数字开头，一个描述性的后缀结尾。数字前缀是必须的，用于记录移植是否成功。后缀仅是为了提高可读性，以方便理解。

移植js里的exports的函数接受一个deployer对象作为第一个参数。这个对象用于发布过程，提供了一个清晰的语法支持，同时提供一些通过的合约部署职责，比如保存发布的文件以备稍后使用。deployer对象是用来缓存(stage)发布任务的主要操作接口。API接口见后说明。

像所有其它在Truffle中的代码一样，Truffle为你提供了你自己代码的合约抽象层(contract abstractions)，并且进行了初始化，以方便你可以便利的与以太坊的网络交互。这些抽象接口是发布流程的一部分，稍后你将会看到。

初始移植 Truffle需要一个移植合约来使用移植特性。这个合约内需要指定的接口，但你可以按你的意味修改合约。对大多数工程来说，这个合约会在第一次移植时进行的第一次部署，后续都不会再更新。通过truffle init创建一个全新工程时，你会获得一个默认的合约。

文件名:contracts/Migration.sol

contract Migrations { address public owner;

// A function with the signature `last_completed_migration()`, returning a uint, is required. uint public last\_completed\_migration;

modifier restricted() { if (msg.sender == owner) \_ }

function Migrations() { owner = msg.sender; }

// A function with the signature `setCompleted(uint)` is required. function setCompleted(uint completed) restricted { last\_completed\_migration = completed; }

function upgrade(address new\_address) restricted { Migrations upgraded = Migrations(new\_address); upgraded.setCompleted(last\_completed\_migration); } } 如果你想使用移植特性，你必须在你第一次部署合约时，部署这个合约。可以使用如下方式来创建一次移植。

文件名：migrations/1\_initial\_migrations.js

module.exports = function(deployer) { // Deploy the Migrations contract as our only task deployer.deploy(Migrations); }; 由此，你可以接着创建递增的数字前缀来部署其它合约。

部署器(deployer) 你的移植文件会使用部署器来缓存部署任务。所以，你可以按一定顺序排列发布任务，他们会按正确顺序执行。

// Stage deploying A before B deployer.deploy(A); deployer.deploy(B); 另一选中可选的部署方式是使用Promise。将部署任务做成一个队列，是否部署依赖于前一个合约的执行情况。

---

*Originally published on [paedy](https://paragraph.com/@paedy/solidity)*
