【区块链】Truffle 部署 编译 测试 智能合约 的 完整实践操作
本文首發自我的CSDN博客,原文鏈接如下
blog.csdn.net/diandianxiy…
目標
- 搭建開發環境
- 創建一個Truffle項目
- 編寫智能合約
- 編譯轉移智能合約
- 測試智能合約
- 創建用戶界面連接智能合約
- 在瀏覽器中訪問Dapp
搭建開發環境
- Node.js v6+ LTS and npm (comes with Node)
- Git
這里配置腳本略過。。。。
xiaoyu@LIXIAOYUdeMacBook-Pro.com? node -v v8.5.0xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm -v 5.4.2xiaoyu@LIXIAOYUdeMacBook-Pro.com? git --version git version 2.13.5 (Apple Git-94)復制代碼xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm install -g ethereumjs-testrpc /usr/local/bin/testrpc -> /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js> fsevents@1.1.2 install /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/fsevents > node installevents.js:182throw er; // Unhandled 'error' event^Error: spawn node-pre-gyp ENOENTat _errnoException (util.js:1026:11)at Process.ChildProcess._handle.onexit (internal/child_process.js:192:19)at onErrorNT (internal/child_process.js:374:16)at _combinedTickCallback (internal/process/next_tick.js:138:11)at process._tickCallback (internal/process/next_tick.js:180:9)at Function.Module.runMain (module.js:667:11)at startup (bootstrap_node.js:201:16)at bootstrap_node.js:626:3> uglifyjs-webpack-plugin@0.4.6 postinstall /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/uglifyjs-webpack-plugin > node lib/post_install.jsnpm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.2 (node_modules/ethereumjs-testrpc/node_modules/fsevents): npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.2 install: `node install` npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1+ ethereumjs-testrpc@4.1.3 added 2 packages, removed 475 packages, updated 238 packages and moved 1 package in 293.194s╭─────────────────────────────────────╮│ ││ Update available 5.4.2 → 5.5.1 ││ Run npm i -g npm to update ││ │╰─────────────────────────────────────╯xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm i -g npm to update /usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx -> /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/update -> /usr/local/lib/node_modules/update/bin/update.js + update@0.7.4 + npm@5.5.1 + to@0.2.9 added 708 packages, removed 2 packages and updated 29 packages in 434.067sxiaoyu@LIXIAOYUdeMacBook-Pro.com? sudo npm install -g ethereumjs-testrpc npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/_yargs@3.10.0@yargs/node_modules/cliui npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/_yargs@3.10.0@yargs/node_modules/decamelize npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/_strip-ansi@3.0.1@strip-ansi/node_modules/ansi-regex npm ERR! path /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/_yargs@3.10.0@yargs/node_modules/cliui npm ERR! code ENOENT npm ERR! errno -2 npm ERR! syscall access npm ERR! enoent ENOENT: no such file or directory, access '/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/_yargs@3.10.0@yargs/node_modules/cliui' npm ERR! enoent This is related to npm not being able to find a file. npm ERR! enoent npm ERR! A complete log of this run can be found in: npm ERR! /Users/xiaoyu/.npm/_logs/2017-10-26T08_09_48_018Z-debug.logxiaoyu@LIXIAOYUdeMacBook-Pro.com? npm install -g truffle /usr/local/bin/truffle -> /usr/local/lib/node_modules/truffle/build/cli.bundled.js + truffle@3.4.11 removed 105 packages and updated 91 packages in 89.658s復制代碼用Truffle Box創建一個Truffle項目
? ~/solidity [16:15:01] xiaoyu@LIXIAOYUdeMacBook-Pro.com? mkdir pet-shop-tutorial ? ~/solidity [16:15:06] xiaoyu@LIXIAOYUdeMacBook-Pro.com? cd pet-shop-tutorialxiaoyu@LIXIAOYUdeMacBook-Pro.com? truffle unbox pet-shop Downloading... Unpacking... Setting up...復制代碼目錄結構
/contracts 智能合約
/migrations 遷移系統來處理智能合約部署
/test 測試
truffle.js 配置文件
其他部分是nodejs的配置文件以及文件夾
編寫智能合約
在contracts中創建Adoption.sol文件
pragma?solidity?^0.4.4;contract?Adoption?{
????address[16]?public?adopters;?//存儲地址
????//采用一個寵物
????function?adopt(uint?petId)?public?returns?(uint)?{
????????require(petId?>=?0?&&?petId?<=?15);
????????adopters[petId]?=?msg.sender;
????????return?petId;
????}
????//返回采用者
????function?getAdopters()?public?returns?(address[16])?{
????????return?adopters;
????}
}復制代碼
編譯轉移智能合約
EVM的測試環境
打開另一個窗口
xiaoyu@LIXIAOYUdeMacBook-Pro.com? testrpc -p 8588 EthereumJS TestRPC v4.1.3 (ganache-core: 1.1.3)Available Accounts ================== (0) 0xd2a54e8087d88889e1857698ceb228493b67bab6 (1) 0x44d32639c3803b9daa7392ff2ea50644153d7721 (2) 0x32d951e2f319edb079764b1c75864497a3132446 (3) 0x82244a630d6031be85ca298376cfa2bd6c7389a6 (4) 0xd3b556b69eb670a250bbc3f15ebefb081d4c7108 (5) 0x9f50cf1b425c6ca97de0128e46a21abd7bda3258 (6) 0x8e0545a4fe9eac1bb2f4683f0c6b36cd4a364a40 (7) 0x200b052f6eaeaa1dc11abcc3101b7a8aca293e70 (8) 0xcbd4c8b9d264367d385d4938c3b390a2eb0f2a62 (9) 0xa769a296f0bbab07e48ca62da5ad5aea4c920580Private Keys ================== (0) a4f66a0654bbd1338a0cc9264624ad9f710f5cd65bbd4aed6f0b20706335e573 (1) cab64a11662597c79a9e866865efbec4b2e1701ed21783f68a61162937baaf8a (2) 9f52f1c63923b390b438212bdd4594d3b479b22024bd193b8a3a600572f697af (3) 452b11e8ea19803b44b474d86c13d7325a387459abe634ad1c64b13eb26d0745 (4) a663ff82b20002942c491e393951e5e366d8cceeff89732690f974f709243260 (5) 7410aba40135ee4fea322a13403b081939d245e7ed534e016090657cbdb6183c (6) 269e44a7c17d591d23a694539a8d6feee3d9894182d4bc663a2f51fc33a3f540 (7) 4f70e8c8f25a1ef2e9057a1b25053d6bceca46b68dfc0548e0c96b16fa9af5eb (8) 6114321e07ba8248509c17f4f0318aaf0edd972986f43ec652a2030b6cfe18bd (9) 37cacf13d9833bb3c63c657b42fed5f87f3806cca4d1cd400cbc5f7c8c2a3cc1HD Wallet ================== Mnemonic: better become piano october library quarter festival ability arrow patch fringe practice Base HD Path: m/44'/60'/0'/0/{account_index}Listening on localhost:8588復制代碼這里注意,我的測試demo指定了端口,那么也要修改對應的配置文件。
truffle.jsmodule.exports = {networks: {development: {host: "localhost",port: 8588,network_id: "*" // Match any network id}} };復制代碼編譯智能合約
? ~/solidity/pet-shop-tutorial [16:27:59] xiaoyu@LIXIAOYUdeMacBook-Pro.com? truffle compile Compiling ./contracts/Adoption.sol... Compiling ./contracts/Migrations.sol... Writing artifacts to ./build/contracts復制代碼遷移智能合約
查看項目目錄,會發現migrations目錄中已經存在了一個文件1_initial_migration.js
我們開始創建第二個文件2_deploy_contracts.js
var Adoption = artifacts.require("./Adoption.sol");module.exports = function(deployer) {deployer.deploy(Adoption); };復制代碼執行遷移
? ~/solidity/pet-shop-tutorial [16:53:30] xiaoyu@LIXIAOYUdeMacBook-Pro.com? truffle migrate Using network 'development'.Running migration: 1_initial_migration.jsDeploying Migrations...... 0x09db8962f99c5e5bdb316882c9f3aff69244df68664c6d90dda7e8c9f5249809Migrations: 0xf7345735ec00a0b797e5469a49b5deaf9131659f Saving successful migration to network...... 0xb6f330b833176db1e94d24c84bab618b6c9205585e9803f7c6fe21f14fec179a Saving artifacts... Running migration: 2_deploy_contracts.jsDeploying Adoption...... 0xb93b24287ebba0dfd091e62fb9d55e188a76412097fdae4a7caf1520b9aaabb9Adoption: 0x424bc3aeeeb6d0a0e0ed8271ce7764b6ad336c7a Saving successful migration to network...... 0x26f08c9da8a6ec12f4edece8a6344a9030bb7fbd97f3b1a4592b93f4aec2dc39 Saving artifacts...復制代碼同時,你在testrpc上還能看到下面的輸出
Listening on localhost:8588 net_version eth_accounts eth_accounts net_version net_version eth_sendTransactionTransaction: 0x09db8962f99c5e5bdb316882c9f3aff69244df68664c6d90dda7e8c9f5249809Contract created: 0xf7345735ec00a0b797e5469a49b5deaf9131659fGas usage: 201556Block Number: 1Block Time: Thu Oct 26 2017 16:58:31 GMT+0800 (CST)eth_newBlockFilter eth_getFilterChanges eth_getTransactionReceipt eth_getCode eth_uninstallFilter eth_sendTransactionTransaction: 0xb6f330b833176db1e94d24c84bab618b6c9205585e9803f7c6fe21f14fec179aGas usage: 41965Block Number: 2Block Time: Thu Oct 26 2017 16:58:31 GMT+0800 (CST)eth_getTransactionReceipt eth_accounts net_version net_version eth_sendTransactionTransaction: 0xb93b24287ebba0dfd091e62fb9d55e188a76412097fdae4a7caf1520b9aaabb9Contract created: 0x424bc3aeeeb6d0a0e0ed8271ce7764b6ad336c7aGas usage: 213057Block Number: 3Block Time: Thu Oct 26 2017 16:58:31 GMT+0800 (CST)eth_newBlockFilter eth_getFilterChanges eth_getTransactionReceipt eth_getCode eth_uninstallFilter eth_sendTransactionTransaction: 0x26f08c9da8a6ec12f4edece8a6344a9030bb7fbd97f3b1a4592b93f4aec2dc39Gas usage: 26965Block Number: 4Block Time: Thu Oct 26 2017 16:58:31 GMT+0800 (CST)eth_getTransactionReceipt復制代碼測試智能合約
在test文件夾中創建文件TestAdoption.sol
pragma?solidity?^0.4.11;import?"truffle/Assert.sol";?//truffle公共的庫
import?"truffle/DeployedAddresses.sol";?//truffle公共的庫
import?"../contracts/Adoption.sol";
contract?TestAdoption?{
????Adoption?adoption?=?Adoption(DeployedAddresses.Adoption());
????//?測試?adopt()
????function?testUserCanAdoptPet()?{
????????uint?returnedId?=?adoption.adopt(8);?//調用輸入參數
????????uint?expected?=?8;?//期望的結果
????????Assert.equal(returnedId,?expected,?"Adoption?of?pet?ID?8?should?be?recorded.");?//判斷如果沒有就拋出異常
????}
????//?單個測試
????function?testGetAdopterAddressByPetId()?{
????????address?expected?=?this;
????????address?adopter?=?adoption.adopters(8);
????????Assert.equal(adopter,?expected,?"Owner?of?pet?ID?8?should?be?recorded.");
????}
????//?所有的測試
????function?testGetAdopterAddressByPetIdInArray()?{
????????address?expected?=?this;
????????address[16]?memory?adopters?=?adoption.getAdopters();
????????Assert.equal(adopters[8],?expected,?"Owner?of?pet?ID?8?should?be?recorded.");
????}
}復制代碼
運行測試命令
xiaoyu@LIXIAOYUdeMacBook-Pro.com? truffle test Using network 'development'.Compiling ./contracts/Adoption.sol... Compiling ./test/TestAdoption.sol... Compiling truffle/Assert.sol... Compiling truffle/DeployedAddresses.sol...Compilation warnings encountered:truffle/Assert.sol:114:20: Warning: This declaration shadows an existing declaration.function equal(string A, string B, string message) constant returns (bool result) {^------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:137:23: Warning: This declaration shadows an existing declaration.function notEqual(string A, string B, string message) constant returns (bool result) {^------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:206:20: Warning: This declaration shadows an existing declaration.function equal(bytes32 A, bytes32 B, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:226:23: Warning: This declaration shadows an existing declaration.function notEqual(bytes32 A, bytes32 B, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:286:20: Warning: This declaration shadows an existing declaration.function equal(address A, address B, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:305:23: Warning: This declaration shadows an existing declaration.function notEqual(address A, address B, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:403:20: Warning: This declaration shadows an existing declaration.function equal(bool A, bool B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:426:23: Warning: This declaration shadows an existing declaration.function notEqual(bool A, bool B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:451:20: Warning: This declaration shadows an existing declaration.function equal(uint A, uint B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:474:23: Warning: This declaration shadows an existing declaration.function notEqual(uint A, uint B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:497:22: Warning: This declaration shadows an existing declaration.function isAbove(uint A, uint B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:520:24: Warning: This declaration shadows an existing declaration.function isAtLeast(uint A, uint B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:543:22: Warning: This declaration shadows an existing declaration.function isBelow(uint A, uint B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:566:23: Warning: This declaration shadows an existing declaration.function isAtMost(uint A, uint B, string message) constant returns (bool result) {^----^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:635:20: Warning: This declaration shadows an existing declaration.function equal(int A, int B, string message) constant returns (bool result) {^---^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:658:23: Warning: This declaration shadows an existing declaration.function notEqual(int A, int B, string message) constant returns (bool result) {^---^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:681:22: Warning: This declaration shadows an existing declaration.function isAbove(int A, int B, string message) constant returns (bool result) {^---^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:704:24: Warning: This declaration shadows an existing declaration.function isAtLeast(int A, int B, string message) constant returns (bool result) {^---^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:727:22: Warning: This declaration shadows an existing declaration.function isBelow(int A, int B, string message) constant returns (bool result) {^---^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:750:23: Warning: This declaration shadows an existing declaration.function isAtMost(int A, int B, string message) constant returns (bool result) {^---^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:1267:27: Warning: This declaration shadows an existing declaration.function balanceEqual(address A, uint b, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:1287:30: Warning: This declaration shadows an existing declaration.function balanceNotEqual(address A, uint b, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:1306:28: Warning: This declaration shadows an existing declaration.function balanceIsZero(address A, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^,truffle/Assert.sol:1325:31: Warning: This declaration shadows an existing declaration.function balanceIsNotZero(address A, string message) constant returns (bool result) {^-------^ truffle/Assert.sol:64:5: The shadowed declaration is here:uint8 constant A = uint8(byte('a'));^---------------------------------^TestAdoption? testUserCanAdoptPet (100ms)? testGetAdopterAddressByPetId (106ms)? testGetAdopterAddressByPetIdInArray (119ms)3 passing (912ms)復制代碼同時,在testrpc窗口中,輸出如下內容
net_version eth_accounts eth_accounts eth_accounts eth_sendTransactionTransaction: 0x0248e4f5b8ed0130b6c04fb0628747948c4430b2db32ae4b4aecc5837c95a7a9Contract created: 0x44d5b51c7a790edf595f36f647d8782ab95d2043Gas usage: 201556Block Number: 5Block Time: Thu Oct 26 2017 17:29:40 GMT+0800 (CST)eth_newBlockFilter eth_getFilterChanges eth_getTransactionReceipt eth_getCode eth_uninstallFilter eth_sendTransactionTransaction: 0xf25d861fa237ca89ece917d3bfcae990b00253a213e3dfe977c808727bb41621Gas usage: 41965Block Number: 6Block Time: Thu Oct 26 2017 17:29:40 GMT+0800 (CST)eth_getTransactionReceipt eth_accounts eth_sendTransactionTransaction: 0x3bc4a4f9a6a29e336135a0617b9dcda72af62f8ed6ba8cdcb52e2c13b9c0b9c1Contract created: 0x7e434775cefce86de3c944aeb840b80ffa397e6fGas usage: 213057Block Number: 7Block Time: Thu Oct 26 2017 17:29:40 GMT+0800 (CST)eth_newBlockFilter eth_getFilterChanges eth_getTransactionReceipt eth_getCode eth_uninstallFilter eth_sendTransactionTransaction: 0x8e9a560c91b97f4fe1020f9e4154b063391d4e1b6da522a80e78d572e18e3864Gas usage: 26965Block Number: 8Block Time: Thu Oct 26 2017 17:29:40 GMT+0800 (CST)eth_getTransactionReceipt evm_snapshot Saved snapshot #1 net_version eth_sendTransaction net_version eth_sendTransactionTransaction: 0xbcca837fc7693ae43eef2210f88f5b59ada90c2c56250558bdee776417c6ce8dContract created: 0x16e910a876a0ef1ad4fceb7b15b0ed1e34212a3fGas usage: 141661Block Number: 9Block Time: Thu Oct 26 2017 17:29:40 GMT+0800 (CST)eth_newBlockFilterTransaction: 0x8ad5172333283066102aada539d0b17f14a3a13b5bc996b8baca49296d625045Contract created: 0x7d49d66afb1fa72446cbbeb2dc7f43237a2895d9Gas usage: 4630196Block Number: 10Block Time: Thu Oct 26 2017 17:29:40 GMT+0800 (CST)eth_newBlockFilter eth_getFilterChanges eth_getFilterChanges eth_getTransactionReceipt eth_getTransactionReceipt eth_getCode eth_getCode eth_uninstallFilter eth_uninstallFilter eth_sendTransactionTransaction: 0x4a9374f9c1da7266c44b9c3f191572a79938bf446e9261a910904fbd86b019efContract created: 0x2411f93ad68e7a071ad6b116614d4a45049a2e36Gas usage: 425816Block Number: 11Block Time: Thu Oct 26 2017 17:29:41 GMT+0800 (CST)eth_newBlockFilter eth_getFilterChanges eth_getTransactionReceipt eth_getCode eth_uninstallFilter eth_blockNumber eth_sendTransactionTransaction: 0xc77b4f897c7ebcd27022c0b677589b6a3611384f5734660ec422cde74f0bec24Gas usage: 48908Block Number: 12Block Time: Thu Oct 26 2017 17:29:41 GMT+0800 (CST)eth_getTransactionReceipt eth_blockNumber eth_sendTransactionTransaction: 0xbc11d4af9475b481271d824c3ba492d7eb23a204608c3da790b77cd8509d518eGas usage: 29062Block Number: 13Block Time: Thu Oct 26 2017 17:29:41 GMT+0800 (CST)eth_getTransactionReceipt eth_blockNumber eth_sendTransactionTransaction: 0x64e35489fcad832bfce85d305726922c2c2a97dcb897ffbfc4a69b0649fc7244Gas usage: 36064Block Number: 14Block Time: Thu Oct 26 2017 17:29:41 GMT+0800 (CST)eth_getTransactionReceipt復制代碼創建用戶界面連接智能合約
安裝web3
xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm install -g web3 npm WARN deprecated fs-promise@2.0.3: Use mz or fs-extra^3.0 with Promise Support npm WARN deprecated tar.gz@1.0.7: ?? WARNING ?? tar.gz module has been deprecated and your application is vulnerable. Please use tar module instead: https://npmjs.com/tar npm WARN deprecated minimatch@0.3.0: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue> scrypt@6.0.3 preinstall /usr/local/lib/node_modules/web3/node_modules/scrypt > node node-scrypt-preinstall.js> scrypt@6.0.3 install /usr/local/lib/node_modules/web3/node_modules/scrypt > node-gyp rebuildSOLINK_MODULE(target) Release/copied_files.nodeCC(target) Release/obj.target/scrypt_wrapper/src/util/memlimit.oCC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/keyderivation.oCC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/pickparams.oCC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/hash.oLIBTOOL-STATIC Release/scrypt_wrapper.aCC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/crypto/crypto_scrypt.oCC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.oCC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/util/warnp.oCC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/alg/sha256.oCC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/util/insecure_memzero.oCC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.oLIBTOOL-STATIC Release/scrypt_lib.aCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_common.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_async.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_sync.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_kdf_async.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_kdf_sync.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_kdf-verify_sync.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_kdf-verify_async.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_hash_sync.oCXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_hash_async.oCXX(target) Release/obj.target/scrypt/scrypt_node.oSOLINK_MODULE(target) Release/scrypt.node> sha3@1.2.0 install /usr/local/lib/node_modules/web3/node_modules/sha3 > node-gyp rebuildCXX(target) Release/obj.target/sha3/src/addon.o ../src/addon.cpp:59:36: warning: 'NewInstance' is deprecated [-Wdeprecated-declarations]info.GetReturnValue().Set(cons->NewInstance(argc, argv));^ /Users/xiaoyu/.node-gyp/8.5.0/include/node/v8.h:3787:3: note: 'NewInstance' has been explicitly marked deprecated hereV8_DEPRECATED("Use maybe version",^ /Users/xiaoyu/.node-gyp/8.5.0/include/node/v8config.h:332:29: note: expanded from macro 'V8_DEPRECATED'declarator __attribute__((deprecated))^ 1 warning generated.CXX(target) Release/obj.target/sha3/src/displayIntermediateValues.oCXX(target) Release/obj.target/sha3/src/KeccakF-1600-reference.oCXX(target) Release/obj.target/sha3/src/KeccakNISTInterface.oCXX(target) Release/obj.target/sha3/src/KeccakSponge.oSOLINK_MODULE(target) Release/sha3.node> websocket@1.0.24 install /usr/local/lib/node_modules/web3/node_modules/websocket > (node-gyp rebuild 2> builderror.log) || (exit 0)CXX(target) Release/obj.target/bufferutil/src/bufferutil.oSOLINK_MODULE(target) Release/bufferutil.nodeCXX(target) Release/obj.target/validation/src/validation.oSOLINK_MODULE(target) Release/validation.node + web3@1.0.0-beta.24 added 289 packages in 68.85s復制代碼打開文件/src/js/app.js
下面的代碼展示了如何調用web3,調用合約的方法,以及綁定數據到UI
App = {web3Provider: null,contracts: {},init: function() {// Load pets.$.getJSON('../pets.json', function(data) {var petsRow = $('#petsRow');var petTemplate = $('#petTemplate');for (i = 0; i < data.length; i ++) {petTemplate.find('.panel-title').text(data[i].name);petTemplate.find('img').attr('src', data[i].picture);petTemplate.find('.pet-breed').text(data[i].breed);petTemplate.find('.pet-age').text(data[i].age);petTemplate.find('.pet-location').text(data[i].location);petTemplate.find('.btn-adopt').attr('data-id', data[i].id);petsRow.append(petTemplate.html());}});return App.initWeb3();},initWeb3: function() {// web3入口if (typeof web3 !== 'undefined') {App.web3Provider = web3.currentProvider;} else {// 測試網絡App.web3Provider = new Web3.providers.HttpProvider('http://localhost:8588'); //這里是我指定的端口88}web3 = new Web3(App.web3Provider);return App.initContract();},initContract: function() {//加載Adoption.json$.getJSON('Adoption.json', function(data) {// 智能合約實例化var AdoptionArtifact = data;App.contracts.Adoption = TruffleContract(AdoptionArtifact);// 設置合約提供者App.contracts.Adoption.setProvider(App.web3Provider);// 檢索操作return App.markAdopted();});return App.bindEvents();},bindEvents: function() {$(document).on('click', '.btn-adopt', App.handleAdopt);},markAdopted: function(adopters, account) {//實例var adoptionInstance;App.contracts.Adoption.deployed().then(function(instance) {adoptionInstance = instance;return adoptionInstance.getAdopters.call();}).then(function(adopters) {for (i = 0; i < adopters.length; i++) {if (adopters[i] !== '0x0000000000000000000000000000000000000000') {$('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);}}}).catch(function(err) {console.log(err.message);});},handleAdopt: function() {event.preventDefault();var petId = parseInt($(event.target).data('id'));var adoptionInstance;web3.eth.getAccounts(function(error, accounts) {if (error) {console.log(error);}var account = accounts[0];App.contracts.Adoption.deployed().then(function(instance) {adoptionInstance = instance;// Execute adopt as a transaction by sending accountreturn adoptionInstance.adopt(petId, {from: account});}).then(function(result) {return App.markAdopted();}).catch(function(err) {console.log(err.message);});});}};$(function() {$(window).load(function() {App.init();}); });復制代碼在瀏覽器中運行dapp
安裝MetaMask到瀏覽器
- 安裝擴展程序
- 創建測試網絡賬戶
- 從其他測試網絡錢包轉移eth
安裝和配置lite-server
打開bs-config.json文件
{"server": {"baseDir": ["./src", "./build/contracts"]} }復制代碼打開package.json文件,下面配置了lite-server的部分
"scripts": {"dev": "lite-server","test": "echo \"Error: no test specified\" && exit 1" },復制代碼當運行npm run dev的時候,就會啟動lite-server
運行Dapp
? ~/solidity/pet-shop-tutorial [17:35:33] xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm run dev> pet-shop@1.0.0 dev /Users/xiaoyu/solidity/pet-shop-tutorial > lite-serversh: lite-server: command not found npm ERR! file sh npm ERR! code ELIFECYCLE npm ERR! errno ENOENT npm ERR! syscall spawn npm ERR! pet-shop@1.0.0 dev: `lite-server` npm ERR! spawn ENOENT npm ERR! npm ERR! Failed at the pet-shop@1.0.0 dev script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.npm ERR! A complete log of this run can be found in: npm ERR! /Users/xiaoyu/.npm/_logs/2017-10-26T10_20_42_191Z-debug.log復制代碼報錯了。。。。
xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm install -g lite-server npm WARN deprecated express@2.5.11: express 2.x series is deprecated npm WARN deprecated connect@1.9.2: connect 1.x series is deprecated /usr/local/bin/lite-server -> /usr/local/lib/node_modules/lite-server/bin/lite-server> fsevents@1.1.2 install /usr/local/lib/node_modules/lite-server/node_modules/fsevents > node install[fsevents] Success: "/usr/local/lib/node_modules/lite-server/node_modules/fsevents/lib/binding/Release/node-v57-darwin-x64/fse.node" already installed Pass --update-binary to reinstall or --build-from-source to recompile + lite-server@2.3.0 added 417 packages in 499.895s ? ~/solidity/pet-shop-tutorial [18:30:10] xiaoyu@LIXIAOYUdeMacBook-Pro.com? npm run dev > pet-shop@1.0.0 dev /Users/xiaoyu/solidity/pet-shop-tutorial > lite-server** browser-sync config ** { injectChanges: false,files: [ './**/*.{html,htm,css,js}' ],watchOptions: { ignored: 'node_modules' },server: { baseDir: [ './src', './build/contracts' ],middleware: [ [Function], [Function] ] } } [Browsersync] Access URLs:-------------------------------------Local: http://localhost:3000External: http://10.0.178.198:3000-------------------------------------UI: http://localhost:3001UI External: http://10.0.178.198:3001------------------------------------- [Browsersync] Serving files from: ./src [Browsersync] Serving files from: ./build/contracts [Browsersync] Watching files... 17.10.26 18:31:20 200 GET /index.html 17.10.26 18:31:20 200 GET /css/bootstrap.min.css 17.10.26 18:31:21 200 GET /js/bootstrap.min.js 17.10.26 18:31:21 200 GET /js/web3.min.js 17.10.26 18:31:21 200 GET /js/app.js 17.10.26 18:31:21 200 GET /js/truffle-contract.js 17.10.26 18:31:24 200 GET /pets.json 17.10.26 18:31:24 200 GET /Adoption.json 17.10.26 18:31:24 200 GET /images/french-bulldog.jpeg 17.10.26 18:31:24 200 GET /images/boxer.jpeg 17.10.26 18:31:24 200 GET /images/scottish-terrier.jpeg 17.10.26 18:31:24 200 GET /images/golden-retriever.jpeg 17.10.26 18:31:24 404 GET /favicon.ico復制代碼然后會自動打開瀏覽器,http://localhost:3000/
示例網站點擊adopt按鈕,會跳出提示,支付合約費用,完成調用。
總結
Truffle能完成智能合約的整套流程。
Truffle Box 提供了現成的項目,可以快速上手。
Truffle官網文檔夠詳細,點個贊。
參考資料
- truffleframework.com/docs/gettin…
- truffleframework.com/tutorials/p…
- github.com/ethereumjs/…
- truffleframework.com/boxes/
- github.com/trufflesuit…
- github.com/ethereum/we…
- metamask.io/
總結
以上是生活随笔為你收集整理的【区块链】Truffle 部署 编译 测试 智能合约 的 完整实践操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL 第二篇:增删改查
- 下一篇: 你知道Unity IoC Contain