0x1 环境搭建
本次Demo创建使用全新Ubuntu18.04系统进行, 所以会安装所需要的全部内容, 包括Node.js / npm / ganache-cli / truffle, 可以选择安装yarn. 它们的功能和文档都可以在其官网查询,在此不再赘述.
- 安装git环境 <code>sudo apt install git</code>
- 安装Node.js <code>sudo apt install nodejs</code>
- 安装npm <code>sudo apt install npm</code>
- 安装ganache-cli <code>sudo npm install -g ganache-cli</code>
- 安装truffle <code>sudo npm install -g truffle</code>
- 安装yarn <code>sudo npm install yarn -g</code>
- 安装curl <code>sudo apt install curl</code>
补充:
0x2 部署本地以太猫合约
环境安装好后, 我们就可以在本地部署Dapp需要的合约文件以及其他内容了. 本次例子使用Truffle提供的以太猫合约(Cheshire). 具体操作如下:
新建一个空文件夹用来放置项目文件:
mkdir Cheshire
cd Cheshire
使用truffle box下载和解压项目文件
<code>truffle unbox endless-nameless-inc/cheshire</code>
执行此命令后显示以下内容表示成功。
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!
Commands:
Start Cheshire: yarn start
Open Cheshire dashboard: yarn run dashboard
Run Cheshire script: yarn run script ./scripts/yourscript.js
Mine blocks: yarn run mine <num blocks>
Help / System status: yarn run help
Compile contracts: truffle compile
Migrate contracts: truffle migrate
Test contracts: truffle test
若要运行Cheshire, 执行
yarn start
这一句命令做了一下几点事情:
- 运行一个以太坊的测试网络(调用ganache-cli)
- 部署以太猫的 KittyCore, SaleClockAuction, 和 SiringClockAuction 合约到测试网络
- 启动本地以太猫API服务
- 执行
/scripts/setup.js
当然yarn start
命令可以用truffle compile
和ganache-cli
等命令来分别执行以达到相同效果, yarn 是对命令的组合.
yarn命令的输出如下:
> Starting database...
> Starting testnet...
> Compiling contracts...
> Deploying CryptoKitties contracts to testnet...
> Starting local CryptoKitties API server...
> Running setup script...
Cheshire is live 😺 Here's what's inside:
Available Accounts
====================
(0) 0x182fc09c33fdd6c2f5b2562f3ca721fa954689c8
...
(9) 0xcdf40e926a778d93429b72c341b4a9e0ee8624c4
Private Keys
====================
(0) 0x76a67ae288fd67ea8d4f7fb94f50c36b606d9448db579584af90d52105f9d8cf
...
(9) 0x6e77cfded732de6d423abcaccc45ee8c4bdc2eb3c0c47938acb386ac17c496b8
Testnet Contracts
====================
KittyCore: 0xa751b62893867d0608a2ada5d17d0c43e3433040
SaleClockAuction: 0x1ab49d53d0bff0202ec4b330349b427155bba7ac
SiringClockAuction: 0x671843106e07f9d835d7299381cd14863af18593
Services
====================
Ethereum testnet listening on port 8546
CryptoKitties API listening on port 4000
Cheshire dashboard available at http://localhost:4000
View the above at any time by running `yarn run help`
OK, 到这里本地的以太猫合约就已经在运行了. 现在就可以在此基础上开发Dapp了.
补充:
- Cheshire概览页面, 可以通过访问 http://localhost:4000 查看.
- Cheshire所包含的智能合约比以太猫多了KittyCore这一合约, 在KittyCore合约中定义了一个外部方法
createKitty
, 利用此方法可以将猫放入测试网络合约中.
function createKitty(
uint256 _matronId,
uint256 _sireId,
uint256 _generation,
uint256 _genes,
address _owner
)
external
returns (uint)
{
return _createKitty(_matronId, _sireId, _generation, _genes, _owner);
}
0x3 调用本地以太猫API
与本地以太猫API交互
Cheshire 已经自动导入了初代以太猫, 调用初代以太猫的接口如下:
curl http://localhost:4000/kitties/1
API回复类似如下Json字符串:
{"id":1,"name":"Genesis","generation":0,"created_at":"2017-11-23T06:19:59.000Z","image_url":"https://storage.googleapis.com/ck-kitty-image/0x06012c8cf97bead5deae237070f9587f8e7a266d/1.png","image_url_cdn":"https://img.cn.cryptokitties.co/0x06012c8cf97bead5deae237070f9587f8e7a266d/1.png","color":"sizzurp","bio":"Greetings, human. I am Genesis. The dogs know me as alpha; the cats know me as omega. To your kind, I am a riddle wrapped in an enigma, first found by a user in Mystery, Alaska. I looked into the void and the void looked back. Then I lost interest. I can’t wait to be your new owner!","is_fancy":true,"is_exclusive":true,"fancy_type":"Genesis","language":"en","status":{"is_ready":true,"is_gestating":false,"cooldown":1442058452492,"cooldown_index":0},"purrs":{"count":1385,"is_purred":false},"watchlist":{"count":0,"is_watchlisted":false},"auction":{},"owner":{"address":"0x79bd592415ff6c91cfe69a7f9cd091354fc65a18","image":"19","nickname":"Stimpson J. Cat"},"matron":{},"sire":{},"children":[],"hatched":true,"wrapped":false,"enhanced_cattributes":[],"fancy_ranking":1}
下面的Scripts部分将展示更多的交互数据.
与测试网络下的合约交互
通过命令行下的truffle命令可以在本地以太坊测试网中与以太猫合约进行交互. 命令如下:
truffle console --network cheshire
然后使用 <code>yarn start</code> 命令后出现的某个地址来创建一个KittyCore合约实例. 使用「getKitty」方法来获取初代猫:
truffle(cheshire)> // 记得用自己初始化项目的地址替换下面的地址
truffle(cheshire)> kittyCore = KittyCore.at('0xa751b62893867d0608a2ada5d17d0c43e3433040')
truffle(cheshire)> kittyCore.getKitty(1)
回复数据类似主网合约数据.
0x4 脚本
Cheshire 提供了一个简单的脚本库, 通过导入主网猫的真实数据.
Cheshire provides a simple scripting framework designed to help seed the development environment with realistic data, primarily by importing kitties from mainnet.
一个Cheshire脚本就是一个运行在Cheshire环境下的Node.js模块.
下面是一个从主网导入Bug 猫到本地测试网的脚本示例:
// /scripts/import-bug-cat.js
module.exports = async function importBugCat(cheshire) {
const bugCatIdMainnet = 101
const ownerTestnet = cheshire.accounts[0].address
const kittyIdTestnet = await cheshire.importKitty(bugCatIdMainnet, ownerTestnet)
console.log(`Kitty #${kittyIdTestnet} => ${ownerTestnet}`)
}
你可以通过下面的命令来运行这个脚本:
yarn run script ./scripts/import-bug-cat.js
命令执行结果如下:
yarn run v1.9.4
$ node ./scripts/run-script.js ./scripts/import-bug-cat.js
Kitty #2 => 0x182fc09c33fdd6c2f5b2562f3ca721fa954689c8
Done in 4.86s.
刷新 http://localhost:4000 可以看到数据变化.
关于 Setup 脚本
Cheshire会在最开始执行/scripts/setup.js
, 你可以修改次文件以达到以下目的:
-
部署Dapp合约到测试网. 例如:
const kittyRace = await cheshire.deployContract('KittyRace', process.env.ADDRESS_KITTY_CORE) log('KittyRace deployed at:', kittyRace.address)
-
启动Dapp网页程序, 继承 Cheshire 定义的环境变量.
推荐在
setup.js
文件中定义环境变量APP_START
的内容为启动Dapp网页程序的命令. 就像下面这样:APP_START="cd ~/Projects/kittyrace-web; bundle exec rails server" yarn start
只要将路径传给yarn start
, 就可以用任何脚本来代替setup.js
的执行. 这样就能很方便的设置一些特殊剧情, 例如设置KittyRace中有7个注册的比赛者, 则执行如下命令:
yarn start ./scripts/setup-registered-racers.js 9
Cheshire API 引导
accounts()
返回一组以太坊用户地址「和config.json中定义的内容相同」
contractAddress(contractName)
返回指定合约地址
contractInstance(contractName)
返回指定合约名实例, 这个实例会是一个web3.eth.contract
类型对象
createKitty(matronId, sireId, generation, genes, owner, apiObject)
用给定参数创建一只猫, 并返回猫的ID
async deployContract(contractName, ...constructorArgs)
部署指定合约到测试网络, 并返web3.eth.contract
类型的合约实例.
Cheshire 会在开始时将constract
目录下的所有合约在开始时编译完成.
async importKitty(kittyIdMainnet, ownerTestnet)
将指定ID的猫数据从主网导入到指定测试网, 返回导入后猫在测试网的ID
async importUser(addressMainnet, addressTestnet)
导入特定地址的主网用户信息和用户下猫数据到测试网, 返回测试网用户地址.
Cheshire 环境变量
Cheshire 在运行其他脚本前定义了以下几个变量:
ADDRESS_KITTY_CORE
ADDRESS_SALE_CLOCK_AUCTION
ADDRESS_SIRING_CLOCK_AUCTION
URL_CRYPTO_KITTIES_API
除此之外, 每一个用Cheshire脚本部署的合约都会有一个形如 ADDRESS_<CONTRACT_NAME>
格式的环境变量存储.
<span id="script">###Span<span>
- 修改truffle.js中port: config.portTestnet -> port: 8545, 因为ganache监听端口8545, 而在config.json文件中定义的portTestnet为8546.
const config = require('./config.json')
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
networks: {
cheshire: {
host: 'localhost',
port: 8545,
network_id: 1337,
},
},
}
0x5 总结
truffle是以太坊智能合约的编译/测试框架, ganache-cli则可以快速访问本地搭建的以太坊网络. 借用这两个工具, 就可以快速完成智能合约的开发/测试/部署, 并在此基础上快速开始Dapp的功能开发和测试.
群二维码
网友评论