TronBox 集成 npm
,并且知道项目中的 node_modules 目录(如果存在)。这意味着我们可以通过 npm
来使用和分发合约、dapps、Solidity 的合约库,使我们的代码可供其他人使用,也可以使用其他代码。
包文件布局
使用 TronBox 创建的项目默认具有特定的目录结构,这使得它们可以作为包来使用。虽然这种目录结构不是必需的,但如果作为通用约定(或“事实上的标准”),那么通过 NPM 分发合约和 dapp 会更加容易。
TronBox 包中最重要的目录如下:
/contracts
/build
(包含通过 TronBox 创建的/build/contracts
)
第一个目录是我们的合约目录,其中包含 Solidity 合约源文件,合约文件中允许导入其他的合约,也运行其他人导入这些合约。第二个目录是构建目录,更具体地说是 /build/contracts
,它以 .json
文件的形式保存构建工件(artifacts),构建的 .json
允许其他人使用 JavaScript 无缝地与我们的合约交互(可以在 dapps、脚本和迁移中使用)。
使用包
在项目中使用包时,在使用其他合约代码时有两个地方需要注意:合约代码和 Javascript 代码(迁移文件和测试文件)。后面为每种情况提供了示例,并讨论了利用其他合约和构建工程文件(artifacts)的技术。
安装
在本例中,我们将使用 TronBox 示例库,它提供了一个部署到测试网络的简单名称注册表。为了将它作为依赖,我们必须首先通过 npm 在项目中安装它:
$ cd my_project
$ npm install example-tronbox-library
请注意,上面的第二个命令下载了包并将其放在 my_project/node_modules
目录中,这对于下面的示例很重要。使用 npm
进行可以参考 npm 文档。
在合约代码中使用包
要在合约中使用其他包的合约,像 Solidity 的 import 声明一样简单。我们的导入路径不是 相对或绝对的 ,它表示正在寻找来自特定命名包的文件。使用上面提到的示例库的示例为:
import "example-tronbox-library/contracts/SimpleNameRegistry.sol";
由于路径不是以 ./
开头,因此 TronBox 知道在项目的 node_modules
目录中查找 example-tronbox-library
文件夹。它将为我们所需合约提供路径。
包的部署地址
有时我们希望合约与包内先前部署的合约进行交互。由于部署的地址存在于包的 .json
文件中,因此必须执行额外的步骤才能将这些地址放入合约中。为此,请使合约接受依赖合约的地址,然后使用迁移。以下是项目中存在依赖合约示例以及迁移示例:
Contract: MyContract.sol
pragma solidity ^0.4.13;
import "example-tronbox-library/contracts/SimpleNameRegistry.sol";
contract MyContract {
SimpleNameRegistry registry;
address public owner;
function MyContract {
owner = msg.sender;
}
// Simple example that uses the deployed registry from the package.
function getModule(bytes32 name) returns (address) {
return registry.names(name);
}
// Set the registry if you're the owner.
function setRegistry(address addr) {
require(msg.sender == owner);
registry = SimpleNameRegistry(addr);
}
}
Migration: 3_hook_up_example_library.js
// Note that artifacts.require takes care of creating an abstraction for us.
var SimpleNameRegistry = artifacts.require('example-tronbox-library/SimpleNameRegistry');
module.exports = function (deployer) {
// Deploy our contract, then set the address of the registry.
deployer
.deploy(MyContract)
.then(function () {
return MyContract.deployed();
})
.then(function (deployed) {
return deployed.setRegistry(SimpleNameRegistry.address);
});
};