普京集团娱乐网以太坊应用实战3-基于NodeJS开发编译部署DAPP

.wqpc_wechat_view *{max-width: 100%!important;box-sizing:
border-box!important;-webkit-box-sizing: border-box!important;
word-wrap: break-word!important;} 微信号 功能介绍
在以太坊项目实际开发中,我们必须要有一个测试环境,因为产品环境是需要消耗GAS的。因此我们希望在测试环境测试无误之后再发布到产品环境以太坊链上去。本篇教程讲述如何搭建本地的测试链。1Testnets以太坊的测试网络环境被称为Testnets,拥有几乎和以太坊等效的功能。因此可以在Testnets上开发和测试自己的智能合约,测试发币等等,作为上链前的评估环境。目前Testnets环境有不少,受到开发者喜爱的主要有以下三种:Ropsten(:
一个POW的区块链,非常类似于以太坊,你可以很轻松的进行挖矿操作。Kovan(:
一个POA的区块链,不能挖矿,需要申请(:
一个POA的区块链,不能挖矿,需要申请(
npm install -g ganache-cli快速启动只需要空参运行ganache-cli即可:$
ganache-cliGanache CLI v6.1.6 (ganache-core: 2.1.5)Available
Accounts==================(0) 0x721e4416f6290230274be32f3d68e8194403f5de
(~100 ETH)(1) 0xefbd7fd54126b3a755cce16ab80b6f018eb2cc4a (~100 ETH)(2)
0x3af60c2747c737b37a49cbdaf6d4e3f80794cbcf (~100 ETH)(3)
0x35456a4255a0e8d2525ffd2eccd16e88b8242de7 (~100 ETH)(4)
0xba6b44714329f4578d785b6132e942b8f920ca07 (~100 ETH)(5)
0xfbb8c6da1c3bcfb7e285210f2404364112877a1b (~100 ETH)(6)
0x33e90bf0bc85d18f1fd104aaae22722ab046cfc4 (~100 ETH)(7)
0x88a7e5c3ebd8c36f84dded2b7e15a59473153cf3 (~100 ETH)(8)
0xe025cdf4066b6d8079438dd9eb9d8a30f82a7f1d (~100 ETH)(9)
0x5da32eb8ca2c8fd14c745776633924e4d87cfbe4 (~100 ETH)Private
Keys==================(0)0x7a11088361c7cad64acadce8deaae666a6721d02837523663cb46683b4ed7cda(1)0x3619c935a7f965449a0104935e4e631cba9077c0783cbf77fe0c5f92fd8bb763(2)0x9ac7a2914d651ef3afba681c1c2035909ae6ca93b86ee8fa367b0373c63f9379(3)0x7e4651e35c7e9956e7a18eb4f721fad81a0e608736cda6bdfee6a5ff9ee8b99d(4)0x11f3144b6f041601e80bfeb6fab4b74caff28fd9fb1cdbf3435967deee308592(5)0xf747fbd7e8e85fbf76d6f7c8eb4244d3b72655d5e86648daab6d020f98a0a251(6)0x065d754b60b856a42a6418e13fb625632122433d9b3263b686265fb67cfc550b(7)0x2857ecc4b378de190265245825dc42443370262c119b894dc61f88564d491252(8)0xa86da3e1e8fc33bbd4fcfab2461af10e7d6eaa16002fb9db582aedf8ff92881c(9)0x4a50bb4a4d4d29df2e894ad9d18086e079b7a3e8b8e4960649c5043268e73ae5HD
Wallet==================Mnemonic: hip achieve device country identify
gun drive nest danger run outside windowBase HD Path:
m/44’/60’/0’/0/{account_index}Gas Price==================20000000000Gas
Limit==================6721975Listening on
127.0.0.1:8545可以看到默参运行会直接创建10个钱包账户,初始化一些以太币,并且有非常多的Gas和足够的Gas
Limit,通常来说也足够运行智能合约的测试了。更多可用参数可以参考ganache-cli
–help的输出,可能比较有用的是持久化钱包(–db参数)和监听0.0.0.0(–host参数),以便组建以太坊Testnets。比如这样:#
在某一台主机(我这里是192.168.31.100)上运行$ mkdir -p ganache_db #
数据库目录必须事先创建,否则程序运行报错$ ganache-cli -h 0.0.0.0 –db
ganache_db/….HD Wallet==================Mnemonic: crucial peanut
biology duck casino safe laugh crowd over enrich crane turkeyBase HD
Path: m/44’/60’/0’/0/{account_index}Gas
Price==================20000000000Gas
Limit==================6721975Listening on
0.0.0.0:8545我们以某一台主机为master,监听0.0.0.0,运行ganache-cli,其他参数全都默认。在另一台主机再启动一个ganache-cli,指明从master节点上进行fork:$
mkdir -p ganache_db$ ganache-cli -h 0.0.0.0 -f
–db ganache_db/…Gas
Price==================20000000000Gas
Limit==================6721975Forked Chain==================Location:
: 0Network ID: 1531668183776Time: Mon Jul
16 2018 00:25:09 GMT+0900Listening on 0.0.0.0:8546最后出现了Forked
Chain字样,这样就可以在多个节点上部署区块链,模拟区块链的网络环境。启动模拟环境之后,使用metamask(:

Wallet==================Mnemonic: hard verb crunch rare direct universe
mean gold claw need neutral carryBase HD Path:
m/44’/60’/0’/0/{account_index}按照metamask网站((
8545(如果修改过默认监听端口,那么请使用最后的Custom RPC):然后选择Import
Existing
DEN(因为ganache-cli已经帮我们初始化好了账户,不用自己重新创建了)。在弹出界面中钱包种子填入终端上的Menmonic,初始化密码自己填一个,满足8位即可:之后就可以看到简单的钱包账户界面了:通过Import
Account功能就可以导入其他创建好的账户了:同样账户的私钥已经打印到终端上了,直接用就可以了。本文作者:HiBlock区块链技术布道群-冯宇Ops原文发布于简书原文链接:

普京集团娱乐网 1

在初步了解了以太坊基本概念之后,我们可以着手开始进行开发,此次我们将通过web3.js封装的以太坊接口来与区块链进行交互。应用整体结构如图所示:

群内分享

普京集团娱乐网 2

1.如何实现“互联网规模”共识? 

3.1 以太坊应用结构

2.刘瑾:区块链技术对货币体系及政策的影响分析 |
央行与货币 

获得一个全节点相当耗时,本次实战将使用ganache软件模拟区块链节点,以便快速开发并测试应用。

3.区块链行业研究报告第一期:物联网 

为了便于开发和测试,ganache默认会自动创建10个账户,每个账户有100个以太币。

4. 干货 |
智能合约开发简介 

普京集团娱乐网 3

5.HiBlock社区-Bob带你玩转宠物店-开发实战|3步教你在以太坊上开一家宠物店 

3.2 模拟区块链节点

6.HiBlock社区-淘飞翔-hyperledger开发分享——一线开发者在超级账本项目开发实践 

上图所示,模拟节点的监听地址和端口为127.0.0.1:7545,
在使用web3.js时,我们将传入此地址告诉web3.js应当连接哪一个节点,接下来我们将使用第一个账号(0x627306090abaB3A6e1400e9345bC60c78a8BEf57)创建交易、发送/接受以太币。

7.社区成员王登辉分享-技术小白如何开发一个DAPP区块链应用(以宠物商店为例)

投票合约设计

我们使用Solidity语言来编写合约,合约的属性用来保存合约的状态,合约中的方法为调用提供接口

普京集团娱乐网 4

3.3 Voting Class

投票合约包含以下内容:

* 构造函数Voting,用来初始化候选人名单

* 投票方法vote, 为指定的候选人投票数加1

*查询方法totalVotesFor(),查询指定候选人的得票数

有几点是区别以往

  1. 合约的状态是持久化到区块链上,对合约状态的修改需要消耗费用

  2. 只有部署合约到区块链上时,才会调用构造函数

3.
合约不可更改,如果想更新合约需要再次部署,但旧的合约仍会在区块链上,合约的状态也依然存在。

技术小白如何开发一个DAPP区块链应用(以宠物商店为例)

投票合约开发

合约代码保存在 voting.sol文件中

编译器要求

pragma solidity ^0.4.18

合约声明

contract Voting{}

contract 关键字用来声明一个合约

字典类型:mapping

mapping(bytes32 => uint8) public votesReceived;

votesReceived是一个键值对,其Key为候选者名字,类型为byte32字符串,值为每个候选者的得票数,类型为uint8

投票方法vote为指定的候选人投票。

function vote(byte32 candidate) public {

    require(validCandidate(candidate));

    votesReceived[candidate] += 1;

}

require 类似断言,只有条件为真时,合约才会继续执行。

validCandidate()方法判断指定的候选人是否是有效的候选人

function validCandidate(byte32 candidate) view public returns (bool) {

    for(uint i = 0; i< candidateList.length; i++) {

        if(candidateList[i] == candidate) {

            return true;

        }

    }

}

完整代码如下:

pragma solidity ^0.4.18;

contract Voting {

      mapping (bytes32 => uint8) public votesReceived;

      bytes32[] public candidateList;

      function Voting(bytes32[] candidateNames) public {

            candidateList = candidateNames;  }

      function totalVotesFor(bytes32 candidate) view public returns
(uint8) {

        require(validCandidate(candidate));

            return votesReceived[candidate];

      }

      function vote(bytes32 candidate) public {

            require(validCandidate(candidate));

            votesReceived[candidate]  += 1;

      }

      function validCandidate(bytes32 candidate) view public returns
(bool) {

            for(uint i = 0; i < candidateList.length; i++) {

                  if (candidateList[i] == candidate) {

                        return true;

                  }

        }

            return false;

      }

}

作者-磨链社区-王登辉

投票合约编译

启动node控制台,初始化web3对象,并向模拟的区块链节点(

> Web3 = require(‘web3’)

> web3 = new Web3(new
Web3.providers.HttpProvider(“”));

> web3.eth.accounts

[ ‘0x627306090abab3a6e1400e9345bc60c78a8bef57’, 
‘0xf17f52151ebef6c7334fad080c5704d77216b732’, 
‘0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef’, 
‘0x821aea9a577a9b44299b9c15c88cf3087f3b5544’, 
‘0x0d1d4e623d10f9fba5db95830f7d3839406c6af2’, 
‘0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e’, 
‘0x2191ef87e392377ec08e7c08eb105ef5448eced5’, 
‘0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5’, 
‘0x6330a553fc93768f612722bb8c2ec78ac90b3bbc’, 
‘0x5aeda56215b167893e80b4fe645ba6d5bab767de’ ]

编译合约,首先载入voting.sol的内容,之后使用solc编译器对合约代码进行编译

code = fs.readFileSync(‘voting.sol’)

solc = require(‘solc’)

compiledCode = solc.compile(code)

=

其编译后的代码有两个重要字段

bytecode: 投票合约编译后的字节码,将要被部署到区块链上

interface: 投票合约接口

原文链接:技术小白如何开发一个DAPP区块链应用(以宠物商店为例)

投票合约部署

在node控制台下执行以下命令

abi = JSON.parse(compiledCode.contracts[‘:Voting’].interface)

contract = web3.eth.contract(abi)

byteCode = compiledCode.contracts[‘:Voting’].bytecode

deployedContract = contract.new([‘zhangsan’,’lisi’,’wama’],{ data:
byteCode,from:web3.eth.accounts[0], gas:4700000})

> deployedContract.address

‘0x8cdaf0cd259887258bc13a92c0a6da92698644c0’

contractInstance = contract.at(deployedContract.address)

contract对象的new()方法将投票合约部署到区块链上,至此我们已经成功部署了投票合约,并且获得一个实例contractInstance,现在可以通过该实例与合约进行交互

文章摘要 

合约交互

通过totalVotesFor方法查看候选人的票数

contractInstance.totalVotesFor.call(‘zhangsan’)

{ [String: ‘0’] s: 1, e: 0, c: [ 0 ] }

vote()投票给候选人,下面的代码给zhangsan 投了二次票

> contractInstance.vote(‘zhangsan’,{from:web3.eth.accounts[0]})

‘0x7fd48761ba8f1fb83239ad6c5da1eff16cbec5259f6c60d28c5464523ac17f6f’

>contractInstance.vote(‘zhangsan’,{from:web3.eth.accounts[0]})

‘0xcd479e1b7d492dc608d584178adce1181e0d251974f70a1cac3f36c00a9eb27b’

再次通过totalVotesFor查看zhangsan的得票数

> contractInstance.totalVotesFor.call(‘zhangsan’).toString()

‘2’

每进行一次投票就产生一次交易,voteForCandidate()将返回交易的凭证,任何时候都可以通过交易凭证查看交易

普京集团娱乐网 5

3.4 transactions

【本文目标】 

总结

当前为止我们已经接触到的相关知识点

  1. nodejs 和 ganache 作为开发环境开发编译部署合约

  2. 开发了简单的投票合约,并编译部署到了区块链节点

  3. 使用nodejs控制台与合约进行交互

  4. 所有数据保存到了区块链,不可修改

  5. 可独立验证每个候选人获得了多少投票

后续将使用Truffle框架构建此投票应用。

通过逐步的指导和截图举证,一步步带领一个技术小白完成一个宠物商店DAPP应用的开发和部署。 

【环境前置条件】 

参考《第一课
如何在WINDOWS环境下搭建以太坊开发环境》,已完成Ubuntu的安装,已完成TRUFFLE,Ganache-cli,lite-server的安装; 

本案例是通过WINDOWS的XSHELL客户端同本机的Ubuntu命令操作进行的。 

已在本地WIDOWS环境完成MetaMask轻钱包客户端的安装。 

最好遵循从头开始的课程学习顺序。不过如果你想半途插入实操学习,问题也不大,遇到障碍时反向找对应文章的指导内容即可完成。 

【技术收获】 

从本实践中,你可以学习到: 

搭建智能合约开发环境 

创建Truffle项目 

编写智能合约 

编译和部署智能合约到区块链 

如何通过Web3和智能合约交互 

MetaMask 的使用 

【实操课程列表】 

第一课 如何在WINDOWS环境下搭建以太坊开发环境 

第二课 如何实现以太坊最简智能合约“Hello World”的运行 

第四课 以太坊开发框架Truffle从入门到实战 

(未列出的课程为知识普及的非实操类课程,所有区块链文章参考“区块链入口”专栏)

下载/编写TRUFFLE框架的智能合约 

项目背景 

Pete有一个宠物店,有16只宠物狗,他想开发一个去中心化应用,让大家来领养宠物。在truffle
box中,已经提供了pet-shop的网站部分的代码,我们只需要编写合约及交互部分。 

【官网原始参考】 

代码框架下载:http://truffleframework.com/boxes/pet-shop 

开发指导:http://truffleframework.com/tutorials/pet-shop

环境搭建 

环境需要NodeJS, Truffle,Ganache-Cli, Lite-Server,
Meta-Mask等程序,按照步骤可以参考《第一课
如何在WINDOWS环境下搭建以太坊开发环境》
搜索对应关键字在已安装的UBUNTU操作系统完成安装。 

安装Node:

sudo apt-get install curl

curl -sL | sudo -E bash

sudo apt-get install -y nodejs

安装 Truffle :

npm install -g truffle

安装Ganache

sudo npm install -g ganache-cli

【说明】Ganache(或Ganache CLI)已经取代了 testrpc。

4.Lite-Server, Meta-Mask安装 

本文后面章节描述。

创建项目 

建立项目目录并进入

mkdir dapp-guide-pet-shop

cd dapp-guide-pet-shop

使用truffle unbox 创建项目 

下载官方程序代码

truffle unbox pet-shop

输出成功结果:

Downloading…

Unpacking…

Setting up…

Unbox successful. Sweet!

Commands:

  Compile:        truffle compile

  Migrate:        truffle migrate

  Test contracts: truffle test

  Run dev server: npm run dev

项目目录结构 

contracts/
智能合约的文件夹,所有的智能合约文件都放置在这里,里面包含一个重要的合约Migrations.sol(稍后再讲) 

migrations/ 用来处理部署(迁移)智能合约
,迁移是一个额外特别的合约用来保存合约的变化。 

test/ 智能合约测试用例文件夹 

truffle.js/ 配置文件 

其他代码可以暂时不用管 

【说明】如果想了解TRUFFLE框架更详细的内容,可参考文章《第四课
以太坊开发框架Truffle从入门到实战》

编写智能合约 

智能合约承担着分布式应用的后台逻辑和存储。智能合约使用solidity编写。 

在contracts目录下,添加合约文件Adoption.sol

pragma solidity ^0.4.17;

contract Adoption {

  address[16] public adopters;  // 保存领养者的地址

    // 领养宠物

  function adopt(uint petId) public returns (uint) {

    require(petId >= 0 && petId <= 15);  // 确保id在数组长度内

    adopters[petId] = msg.sender;        // 保存调用这地址

    return petId;

  }

  // 返回领养者

  function getAdopters() public view returns (address[16]) {

    return adopters;

  }

}

编译部署智能合约

Truffle集成了一个开发者控制台,可用来生成一个开发链用来测试和部署智能合约。 

编译 

Solidity是编译型语言,需要把可读的Solidity代码编译为EVM字节码才能运行。 

进入dapp的根目录dapp-guide-pet-shop执行命令,

> truffle compile

输出

Compiling ./contracts/Adoption.sol…

Writing artifacts to ./build/contracts

编写部署代码

编译之后,就可以部署到区块链上。 

在migrations文件夹下已经有一个1_initial_migration.js部署脚本,用来部署Migrations.sol合约。 

Migrations.sol 用来确保不会部署相同的合约。

现在我们来创建一个自己的部署脚本2_deploy_contracts.js

var Adoption = artifacts.require(“Adoption”);

module.exports = function(deployer) {

  deployer.deploy(Adoption);

};

安装启动Ganache测试环境 

在执行部署之前,需要确保有一个区块链运行, 可以使用 

Ganache来开启一个私链来进行开发测试。 

参考文章《第一课 如何在WINDOWS环境下搭建以太坊开发环境》
对应的章节,完成ganache-cli的安装。

sudo npm install -g ganache-cli

在新的命令行窗口运行ganache-cli程序:

cd /usr/work/Ganache

ganache-cli >> trace.log

这个>>目的是把ganache-cli的结果输出到文件,便于后面复制钱包地址用于查看ETH余额。作者实践时把这2行命令合并成一行执行。

ganache-cli >> /usr/work/Ganache/trace.log

这个命令窗口用于运行Ganache程序输出,不可关闭。需要新开一个命令窗口用于执行TRUFFLE的命令。

普京集团娱乐网 6

打开trace.log文件,可查看默认启动的10个钱包账户和对应的私钥地址:

Available Accounts

==================

(0) 0x7554cc8c721712adde43e67a5669225bbe8f21f6

(1) 0x3e6ce6a43c1fa565b5b90963bef090625d3edc6c

(2) 0xeb2eb6ed4b325e77f5a597497ec5ffaa2f5c2650

(3) 0x1de061d5f225533f7e3c38a5905a6ca2ecb3e55a

(4) 0x3ec2e1ed3f47fc7ab9cca1fe09afe9fd1feb789b

(5) 0xf27a303880b73a0a287a2e5dc1286098fb49ed63

(6) 0xf3c007932e1de894503166aee3cbf85b4aff0188

(7) 0xe7655733659c14c7c83fb71bd40dc51796592d96

(8) 0x507722000223ca96ac646198709b9ae3f7f49a5a

(9) 0x82b087a83f72cc7dd5ca6ac7787a366b2c3ff143

Private Keys

==================

(0) 629551aa45c594ce822c5b4a378d01cf46fb57c15b69a61eb400a4867ffab002

(1) a90103a95ed805acc52782eaa29eb061f6c2a9431fed3ac18a683ea3143a29b6

(2) c2b13ce370fb235997dc4783ce591a22e5b3909e934dc7c0f61797ce57d5059d

(3) 841d0e1d3dc658ad2f308c7292b4d5c40da158d170cf3ed9001c64b8352cd0c2

(4) 255225aedba340b6ec62e6c86a6202535d7382704b129d022461c69b8341d2dd

(5) c3fd784fc7a46edb5e7cba9e90120e51152a3fbe2d8b97a0c3106791d3bbe87e

(6) f8f90b056c419464d48dcd12ac8e326a31ebe300ea5e245876fe0308c511fbac

(7) 09e20553971b044c1fda8ac88f2ed1dcdff6af0889fc05c2ad4374c52d4f52d7

(8) 142643d0fb6f4a78e0fd291a568b784869927d8f8eee87bf3fbdbf493ec3f425

(9) 8f89d4a05582193cc32f800ecf9419f35b5384abc5db42afd4ec016a54d27716

配置以太坊客户端本地环境 

ruffle.js是truffle的配置文件,位于dapp-guide-pet-shop目录下,启动好以太坊本地结点以后,我们需要让truffle去识别它并使用它,这就需要在truffle.js中配置相关属性:

module.exports = {

  // See

  // for more about customizing your Truffle configuration!

  networks: {

    development: {

      host: “127.0.0.1”,

      port: 8545,

      network_id: “*” // Match any network id

    }

  }

};

执行部署命令

接下来在新的命令窗口执行部署命令

cd /usr/work/dapp-guide-pet-shop

    truffle migrate

执行后,有一下类似的输出,

Using network ‘development’.

Running migration: 1_initial_migration.js

  Deploying Migrations…

  … 0x29612ceea67bc946cc6ae82afbedc546f9a53ba8cab5d804f9025fb8f15e48f8

  Migrations: 0x8af912046664ba26738b811c34068d42216528c0

Saving successful migration to network…

  … 0x6c968a3c492439ab22028e1956360a6b73a02716c436b15234cd29804dac7298

Saving artifacts…

Running migration: 2_deploy_contracts.js

  Deploying Adoption…

  … 0x27448e4f75b608015f3670e3650cf607c882fe7f1a32f98e8a94bf7a406c871c

  Adoption: 0xe42f434105a7e0eacf4f4229c76e1e135d536db6

Saving successful migration to network…

  … 0x9375cd6fa143d01a520c5ed0d46cfe859f482b01e37cf678d751c5db6a278e5f

Saving artifacts…

查看Ganache-cli的输出文件:trace.log,可以看到区块链状态的变化,现在产生了4个区块。

net_version

eth_accounts

eth_accounts

net_version

net_version

eth_sendTransaction

  Transaction:
0x29612ceea67bc946cc6ae82afbedc546f9a53ba8cab5d804f9025fb8f15e48f8

  Contract created: 0x8af912046664ba26738b811c34068d42216528c0

  Gas usage: 268407

  Block Number: 1

  Block Time: Tue Apr 10 2018 09:10:18 GMT+0800 (CST)

eth_newBlockFilter

eth_getFilterChanges

eth_getTransactionReceipt

eth_getCode

eth_uninstallFilter

eth_sendTransaction

  Transaction:
0x6c968a3c492439ab22028e1956360a6b73a02716c436b15234cd29804dac7298

  Gas usage: 41981

  Block Number: 2

  Block Time: Tue Apr 10 2018 09:10:19 GMT+0800 (CST)

eth_getTransactionReceipt

eth_accounts

net_version

net_version

eth_sendTransaction

  Transaction:
0x27448e4f75b608015f3670e3650cf607c882fe7f1a32f98e8a94bf7a406c871c

  Contract created: 0xe42f434105a7e0eacf4f4229c76e1e135d536db6

  Gas usage: 247573

  Block Number: 3

  Block Time: Tue Apr 10 2018 09:10:19 GMT+0800 (CST)

eth_newBlockFilter

eth_getFilterChanges

eth_getTransactionReceipt

eth_getCode

eth_uninstallFilter

eth_sendTransaction

  Transaction:
0x9375cd6fa143d01a520c5ed0d46cfe859f482b01e37cf678d751c5db6a278e5f

  Gas usage: 26981

  Block Number: 4

  Block Time: Tue Apr 10 2018 09:10:20 GMT+0800 (CST)

eth_getTransactionReceipt

这时说明已经智能合约已经部署好了。

测试

现在我们来测试一下智能合约,测试用例可以用 JavaScript or
Solidity来编写,这里使用Solidity。

在test目录下新建一个TestAdoption.sol,编写测试合约

pragma solidity ^0.4.17;

import “truffle/Assert.sol”;  // 引入的断言

import “truffle/DeployedAddresses.sol”;  // 用来获取被测试合约的地址

import “../contracts/Adoption.sol”;      // 被测试合约

contract TestAdoption {

  Adoption adoption = Adoption(DeployedAddresses.Adoption());

  // 领养测试用例

  function testUserCanAdoptPet() public {

    uint returnedId = adoption.adopt(8);

    uint expected = 8;

    Assert.equal(returnedId, expected, “Adoption of pet ID 8 should be
recorded.”);

  }

  // 宠物所有者测试用例

  function testGetAdopterAddressByPetId() public {

    // 期望领养者的地址就是本合约地址,因为交易是由测试合约发起交易,

    address expected = this;

    address adopter = adoption.adopters(8);

    Assert.equal(adopter, expected, “Owner of pet ID 8 should be
recorded.”);

  }

    // 测试所有领养者

  function testGetAdopterAddressByPetIdInArray() public {

  // 领养者的地址就是本合约地址

    address expected = this;

    address[16] memory adopters = adoption.getAdopters();

    Assert.equal(adopters[8], expected, “Owner of pet ID 8 should be
recorded.”);

  }

}

Assert.sol 及
DeployedAddresses.sol是Truffle框架提供,在test目录下并不提供truffle目录。

TestAdoption合约中添加adopt的测试用例

运行测试用例

在终端中,执行

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:1563:9: Warning: Use of the “var” keyword is
deprecated.

        var nstr = _itoa(value, 10);

        ^——^

,truffle/Assert.sol:1580:9: Warning: Use of the “var” keyword is
deprecated.

        var nstr = _utoa(value, 10);

        ^——^

,truffle/Assert.sol:1597:9: Warning: Use of the “var” keyword is
deprecated.

        var nstr = _ltoa(value);

        ^——^

,truffle/Assert.sol:1347:13: Warning: Invoking events without “emit”
prefix is deprecated.

            TestEvent(true, “”);

            ^—————–^

,truffle/Assert.sol:1349:13: Warning: Invoking events without “emit”
prefix is deprecated.

            TestEvent(false, message);

            ^———————–^

  TestAdoption

    ✓ testUserCanAdoptPet (246ms)

    ✓ testGetAdopterAddressByPetId (231ms)

    ✓ testGetAdopterAddressByPetIdInArray (287ms)

  3 passing (2s)

创建用户接口和智能合约交互

我们已经编写和部署及测试好了我们的合约,接下我们为合约编写UI,让合约真正可以用起来。

在Truffle Box pet-shop里,已经包含了应用的前端代码,代码在src/文件夹下。

在编辑器中打开src/js/app.js 

可以看到用来管理整个应用的App对象,init函数加载宠物信息,就初始化web3. 

web3是一个实现了与以太坊节点通信的库,我们利用web3来和合约进行交互。 

初始化web3

接下来,我们来编辑app.js修改initWeb3(): 

删除注释,修改为:

  initWeb3: function() {

    // Is there an injected web3 instance?

    if (typeof web3 !== ‘undefined’) {

      App.web3Provider = web3.currentProvider;

    } else {

      // If no injected web3 instance is detected, fall back to Ganache

      App.web3Provider = new
Web3.providers.HttpProvider(”);

    }

    web3 = new Web3(App.web3Provider);

    return App.initContract();

  }

代码中优先使用 MetaMask提供的web3实例,如果没有则从本地环境创建一个。 

实例化合约

使用truffle-contract会帮我们保存合约部署的信息,就不需要我们手动修改合约地址,修改initContract()代码如下:

initContract: function() {

    //
加载Adoption.json,保存了Adoption的ABI(接口说明)信息及部署后的网络(地址)信息,它在编译合约的时候生成ABI,在部署的时候追加网络信息

    $.getJSON(‘Adoption.json’, function(data) {

      // Get the necessary contract artifact file and instantiate it
with truffle-contract

      // 用Adoption.json数据创建一个可交互的TruffleContract合约实例。

      var AdoptionArtifact = data;

      App.contracts.Adoption = TruffleContract(AdoptionArtifact);

      // Set the provider for our contract

      App.contracts.Adoption.setProvider(App.web3Provider);

      // Use our contract to retrieve and mark the adopted pets

      return App.markAdopted();

    });

    return App.bindEvents();

  },

处理领养

修改markAdopted()代码:

markAdopted: function(adopters, account) {

    var adoptionInstance;

    App.contracts.Adoption.deployed().then(function(instance) {

      adoptionInstance = instance;

      // 调用合约的getAdopters(), 用call读取信息不用消耗gas

      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()代码:

handleAdopt: function(event) {

    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;

        // 发送交易领养宠物

        return adoptionInstance.adopt(petId, {from: account});

      }).then(function(result) {

        return App.markAdopted();

      }).catch(function(err) {

        console.log(err.message);

      });

    });

  }

安装和配置lite-server

【定义】lite-server
是一个全功能的网站架设工具软件包轻量级的,仅适用于开发 的 node 服务器,
它仅支持 web app。 它能够为你打开浏览器,
当你的html或是JavaScript文件变化时,它会识别到并自动帮你刷新浏览器,
还能使用套接字自动注入变化的CSS, 当路由没有被找到时,它将自动后退页面。 

参考文章《第一课 如何在WINDOWS环境下搭建以太坊开发环境》的”(8)安装
lite-server
【可选】”章节完成lite-server的安装。

bs-config.json文件指示了lite-server的工作目录。

{

  “server”: {

    “baseDir”: [“./src”, “./build/contracts”]

  }

}

./src 是网站文件目录 

./build/contracts 是合约输出目录

以此同时,在package.json文件的scripts中添加了dev命令:

{

  “name”: “pet-shop”,

  “version”: “1.0.0”,

  “description”: “”,

  “main”: “truffle.js”,

  “directories”: {

    “test”: “test”

  },

  “scripts”: {

    “dev”: “lite-server”,

    “test”: “echo “Error: no test specified” && exit 1″

  },

  “author”: “”,

  “license”: “ISC”,

  “devDependencies”: {

    “lite-server”: “^2.3.0”

  }

}

当在新的命令窗口运行npm run dev的时候,就会启动lite-server

cd /usr/work/dapp-guide-pet-shop

    npm run dev

正常的运行结果有如下类似输出内容:

> pet-shop@1.0.0 dev /usr/work/dapp-guide-pet-shop

> 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:

    External:


          UI:

UI External:


[Browsersync] Serving files from: ./src

[Browsersync] Serving files from: ./build/contracts

[Browsersync] Watching files…

安装 MetaMask和配置区块链网络 

安装 MetaMask

【定义】MetaMask
是一款插件形式的以太坊轻客户端,开发过程中使用MetaMask和我们的dapp进行交互是个很好的选择。 

作者是在本地WINDOWS的CHROME浏览器上安装MetaMask钱包工具,具体的安装方法参考文章《第一课
如何在WINDOWS环境下搭建以太坊开发环境》的“(7)安装 MetaMask
【可选】”章节。

说明下,最详细的MetaMask安装/配置文章可参考欧阳哥哥的《以太坊钱包MetaMask使用教程》 

配置钱包 

  1. 接受隐私条款 

点击浏览器地址栏右侧,MetaMask的狐狸头图标,第一次使用时,会出一个隐私提示,如下图:

普京集团娱乐网 7

  1. 接受服务条款 

点击Accept按钮,显示的是MetaMask的服务条款,如下图2-2:

普京集团娱乐网 8

Accept按钮默认是灰色的,将滚动条拉到底部,就可以点击Accept按钮了。 

3、创建新账号 

创建新账号:输入一串8位以上的密码,再次重复输入,点击CREATE按钮,即可完成。 

下面以创建新账号为例:

普京集团娱乐网 9

在点击CREATE按钮后,MetaMask会为用户创建12个英文助记词,一定要保存好这些助记词,点击SAVE
SEED WORDS AS
FILE可以将助词词以文件的形式保存到本地,建议使用纸笔手工记录并收藏于安全的地方。

普京集团娱乐网 10

连接开发区块链网络

默认连接的是以太坊主网(左上角显示),选择Custom
RPC,添加Ubuntu的IP地址作为客户自定义RPC网络

链接测试机以太坊客户端成功,菜单有链接成功的橙色√提示。

普京集团娱乐网 11

这是左上角显示为Private Network,此时显示的是默认的Account
1空账号,ETH数量为0。

导入Ganache-cli的第一个钱包账号

查看“trace.log”文件,可以Ganache-cli的第一个默认钱包地址为

(0) 629551aa45c594ce822c5b4a378d01cf46fb57c15b69a61eb400a4867ffab002

(1) a90103a95ed805acc52782eaa29eb061f6c2a9431fed3ac18a683ea3143a29b6

选择MetaMask的“Import Account”输入私钥,获取账号,可以查看对应ETH余额。

普京集团娱乐网 12

普京集团娱乐网 13

第一个钱包账户的余额: 

普京集团娱乐网 14

第二个钱包账户的余额:

普京集团娱乐网 15

至此MetaMask的安装,配置已经完成。 

领养宠物

修改.dapp-guide-pet-shopsrcindex.html文件引用jquery的地址

   

    –>

   

在WINDOWS浏览器输入测试网站地址 

http://192.168.80.144:3000/ 

可以看到宠物商店的入口界面:

普京集团娱乐网 16

点击“Adopt”按钮,领养这个最漂亮的狗狗宝贝。MetaMask会提示我们交易的确认,如图:

普京集团娱乐网 17

点击“SUBMIT”按钮成功后,这个狗狗的按钮变为”SUCCESS”,该狗狗已被包养了。 

普京集团娱乐网 18

查看当前打开的账号ACCOUNT6,发现金额不再是100ETH,而是99.999ETH了。 

普京集团娱乐网 19

恭喜你,开发并成功部署了一个DAPP区块链应用程序,并且领养了几只小狗狗。 

参考 

本文是文章:一步步教你开发、部署第一个Dapp应用:宠物商店的实践课程,并根据作者环境做适当的修改截图。感谢分享指导。 

如有问题,可简书私信联系辉哥。

磨链(mochain)计划各学习小组动态

计划具体内容(负责人)进度

1.磨链入门区块链磨链社区写一本关于区块链入门的书,包括区块链相关技术、经济学、比特币、以太坊、超级账本、EOS、DAG、
IPFS等相关内容,最后加一个磨链的实战项目
一个DAPP的开发(金明杰)目录编写中,人员招募中

2.以太坊入门到精通tower上新建计划14个小模块开始解读(盖盖)3.25出第一版整理内容、门户逐步更新

3.以太坊项目实践磨链社区-以太坊实战在线课程(虞双齐)每周六在线课程、目前已出3期

5.bitcoinbitcoin自问自答-深入挖掘bitcoin疑问(陈烨)3.25前整理计划

6.超级账本整理安排在线课程和内容分享(南瓜地、宣章炯)3月底前整理计划课程

7.IPFS磨链社区官网-已更新两期分享内容(陈德君)持续进行中

10.区块链相关政策解读与商业应用跟踪磨链社区官网-在每日分享更新相关内容(CHONG)持续进行中

磨链计划相关

磨链(mochain)学习小组清单

计划具体内容

1.磨链入门区块链磨链社区写一本关于区块链入门的书,包括区块链相关技术、经济学、比特币、以太坊、超级账本、EOS、DAG、
IPFS等相关内容,最后加一个磨链的实战项目 一个DAPP的开发

2.以太坊入门到精通深入以太坊运行原理、对相关模块定位到源码解读。

3.以太坊项目实践包括环境搭建,开发环境搭建,及相关实践开发

4.以太坊课程设计,相关以太坊内容整理以太坊课程、包括智能合约基础、编写、开发。

5.bitcoinbitcoin相关内容,比特币自问自答

6.超级账本超级账本相关内容。具体待细化

7.IPFS相关内容IPFS filecoin相关内容

8.DAGDAG,字节雪球相关内容

9.区块链基础知识包括密码学、算法、共识机制、P2P网络等相关内容

10.区块链相关政策解读与商业应用跟踪区块链相关政策解读与商业应用跟踪内容,包括最新新闻信息分析分享

11.挖矿相关挖矿原理、挖矿相关内容

12.EOS相关EOS相关内容

13.区块链技术文档翻译区块链技术文档翻译,以太坊,solidity,truffle,超级账本等相关文档

PS:想加入学习小组,请加磨链组织者微信(jackyjin09)。欢迎每一位区块链技术爱好者加入磨链,一块琢磨区块链技术

关于磨链和相关合作

磨链”—取磨炼之意,旨在普及区块链技术,磨炼技术,更好投身区块链行业。有兴趣一块琢磨区块链技术,联系笔者微信(jackyjin09)。 

磨链社区是一个纯粹的技术社区,欢迎相关技术合作,在不违反原则的前提下,积极参与合作。 

你可以在这里找到我们: 

磨链社区公众号: 

普京集团娱乐网 20

1.
磨链社区:http://mochain.info 

  1. Github
    : https://github.com/mochain 

  2. Gitter
    聊天: https://gitter.im/mochain 

4.
知识星球: https://t.zsxq.com/M3BMVZN 

5.
知乎:https://www.zhihu.com/people/mochain 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

CopyRight © 2015-2020 普京集团娱乐网 All Rights Reserved.
网站地图xml地图