美文网首页
第一个去中心化应用

第一个去中心化应用

作者: 高鸿祥 | 来源:发表于2018-12-07 19:16 被阅读44次

    本文内容来自熊丽兵老师在登链学院上的《以太坊Dapp开发实战》课程

    简介

    本文为一个简单的去中心化应用的开发,旨在了解以太坊Dapp开发流程。

    应用效果图如下

    第一个去中心化应用.png

    应用的功能很简单

    浅蓝色部分用来显示区块链上的姓名和年龄信息

    浅绿色部分用来修改区块链上的姓名和年龄信息

    开发流程

    本例在Ubuntu系统下开发,据说在windows下会出现莫名其妙的问题,所以没用。

    本开发示例没有使用任何框架,后续会写truffle框架开发示例

    准备:选择以太坊网络节点、钱包连接节点、remix连接节点
    
    后端:智能合约开发 -> 智能合约测试 -> 智能合约部署
    
    前端:安装web服务器 -> 前端UI设计
    
    交互:web3与智能合约交互
    

    本例的工具选择

    以太坊网络节点:ganache虚拟节点
    
    钱包:metaMask
    
    代码编辑器:Remix(以太坊在线IDE)
    
    web服务器:lite-server
    
    web3版本:web3.js
    
    

    准备

    选择一个以太坊网络节点,然后将钱包和remix跟此节点连接起来,打通环境

    选择以太坊网络节点

    以太坊的节点有很多种:主网、测试网络、geth私链节点、ganache模拟节点

    因为每个交易都需要花钱,这在开发环境下非常不适合,所以开发时不要选择以太坊的主网,这会花费真实的以太币,也不要选择以太坊的测试网络,因为要等待区块的确认,这个过程会占用时间,而开发需要及时反馈。

    这里选择ganache模拟节点

    安装ganache

    ganache有CLI和GUI两个版本,本文安装的是CLI版本。github地址:https://github.com/trufflesuite/ganache-cli

    GUI版本地址:https://github.com/trufflesuite/ganache/releases ,如果想使用图形界面版,选择对应版本下载安装即可

    sudo npm install -g ganache-cli //需要先安装nodejs
    
    开启ganache

    智能合约的测试部署需要在节点上进行,所以这里开启ganache节点。可以单独开一个终端运行ganache

    ganache-cli
    

    钱包连接ganache节点

    以太坊Dapp交易需要花钱,钱存储在钱包里。所以,需要用到钱包。这里使用最常用的MetaMask钱包

    MetaMask(官网:https://metamask.io/ )是一款浏览器插件钱包,不需下载安装客户端,只需添加至浏览器扩展程序即可使用。它不仅是一个简单的钱包,还可以很方便的调试和测试以太坊的智能合约。

    安装MetaMask

    安装可参考此链接:以太坊钱包MetaMask使用教程。基本的使用方法文章里都有介绍

    连接ganache节点

    点击MetaMask的NetWork栏,选择Private Network(ganache节点:localhost 8545),即可连接ganache节点

    导入ganache账户

    点击账户栏,选择 Import Account,输入私钥(启动ganache时会列出十个账户和对应的私钥,选择一个私钥复制过来)即可导入ganache自动创建的账户到MetaMask中。此账户中会默认有100ETH。用此账户来部署合约以及交易。

    Remix连接ganache节点

    Remix的Run界面的Environment选项里选择web3 Provider,弹出的窗口里输入ganache-cli的监听url(http://localhost:8545) ,即可连接上ganache节点

    注意:remix中的使用的账户和MetaMask中使用的账户要一致
    remix默认使用ganache创建的第一个账户,可以点击Account处更换
    MetaMask导入账户时可直接导入第一个账户,就可与remix中的账户对应。

    后端开发

    智能合约开发使用以太坊的在线IDERemix

    Remix使用请参考:教程 | 【Ethereum 智能合约开发笔记】使用 Remix

    Remix编译版本要和智能合约的版本一致,否则会报错。
    如智能合约使用0.4.24,那么remix也要选择0.4.24(Compile页面里选择)

    智能合约开发

    simple.sol

    pragma solidity ^0.4.24;
    
    contract simple{
    
        string name;
        uint age;
    
        //定义事件
        event Instructor(string name, uint age);
    
        function set(string _name, uint _age) public {
            name = _name;
            age = _age;
    
            //触发事件
            emit Instructor(name, age);
        }
    
        function get() public view returns(string, uint) {
            return (name, age);
        }
    }
    

    智能合约测试

    这里不太好测试,后面用truffle时可以很方便的进行测试。要记住,Dapp开发一定要进行测试!这直接关系到钱!

    智能合约部署

    remix的Run页面里点击Deploy(create)按钮,即可把智能合约部署到节点上

    在Deployed Contracts里会看到set和get函数。可以跟智能合约交互
    set后面的输入框里输入"中本聪",18,然后点击set按钮。就将信息写入了区块链,然后点击get按钮,刚才输入的信息就会显示出来。

    前端开发

    项目目录结构

    |-- simple  //项目根目录
        -- index.html
        -- index.css
        -- index.js
    

    安装web服务器环境

    项目开发中,环境的一致性非常重要,这里给项目本身安装web服务器(lite-server),而不需依赖外部的web服务器(如nginx)

    npm install lite-server --save-dev
    

    安装完后会在项目根目录下生成node_modules目录

    |-- simple  //项目根目录
        -- index.html
        -- index.css
        -- index.js
        |-- node_modules
    

    在终端开启服务

    node_modules/lite-server/bin/lite-server
    

    UI设计完后,开启服务后会自动打开网页,就会看到html内容

    UI设计

    基本的UI设计跟传统的App开发一样。

    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>第一个去中心化应用</title>
        <link rel="stylesheet" href="./index.css">
    </head>
    <body>
        <div id="content">
            <h1 id="title">第一个去中心化应用</h1>
            <h2 id="info"></h2>
            <div id="loader"></div>
            <div id="update">
                <div>
                    <label for="name">姓名:</label>
                    <input type="text" id="name">
                </div>
                <div>
                    <label for="age">年龄:</label>
                    <input type="text" id="age">
                </div>
                <button id="button">更新</button>
            </div>
        </div>
    </body>
    </html>
    
    index.css
    body{background:#f0f0f0;}
    #content{width:350px;margin:0 auto;}
    #title{text-align: center;}
    #info{padding:0.5em;background: lightblue;margin:1em 0;}
    #update{padding:1em;background: lightgreen}
    #name{border:none;}#age{border:none;}
    button{margin:1em 0;}
    
    

    web3与智能合约交互

    这里是Dapp的关键部分,前端与智能合约使用RPC协议来交互。web3封装了RPC,提供了更友好的接口来调用.

    web3有很多实现版本,用的最多的使web3.js。本例使用的就是web3.js。github地址:https://github.com/ethereum/web3.js ,详细信息可查看文档

    大体步骤如下

    获取web3对象 -> 得到智能合约实例 -> 调用智能合约方法来交互
    

    修改html页面,在body最后引入js文件

    <!-- 引入jquery -->
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <!-- 引入web3.js 这里的web3.js为0.2版本。1.0版本目前还是beta阶段,等稳定了可更换为1.0版本 -->
    <script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
    <!-- 引入index.js -->
    <script src="./index.js"></script>
    

    index.js

    //设置provider(web3连接到哪个节点)
    if (typeof web3 !== 'undefined') {
        web3 = new Web3(web3.currentProvider);
    } else {
        // Set the provider you want from Web3.providers
        web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    }
    //得到智能合约实例
    //数组里是智能合约的abi。修改智能合约的话abi也会变化,需要更换
    var infoContract = web3.eth.contract([
        {
            "anonymous": false,
            "inputs": [
                {
                    "indexed": false,
                    "name": "name",
                    "type": "string"
                },
                {
                    "indexed": false,
                    "name": "age",
                    "type": "uint256"
                }
            ],
            "name": "Instructor",
            "type": "event"
        },
        {
            "constant": false,
            "inputs": [
                {
                    "name": "_name",
                    "type": "string"
                },
                {
                    "name": "_age",
                    "type": "uint256"
                }
            ],
            "name": "set",
            "outputs": [],
            "payable": false,
            "stateMutability": "nonpayable",
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "get",
            "outputs": [
                {
                    "name": "",
                    "type": "string"
                },
                {
                    "name": "",
                    "type": "uint256"
                }
            ],
            "payable": false,
            "stateMutability": "view",
            "type": "function"
        }
    ])
    
    //地址为部署的智能合约的地址,重新部署的话地址就会改变,需要用新的合约地址
    var simple = infoContract.at('0xa2eefd5ee8a78630d27e3b884b04b53315881942');
    
    //调用合约的方法进行交互。交易是异步的,需要用回调函数来接收结果。结果在result里
    simple.get.call(function(error,result){
        if(!error){
            $("#info").html(`我叫` + result[0] + `, 我今年` + result[1] + `岁了。`);
        }
    });
    //点击更新按钮,更新信息
    $("#button").click(function(){
        $("#loader").show();
        simple.set.sendTransaction($("#name").val(),$("#age").val(),function(error,result){
            if(!error){
                console.log("set ok");
            }
        })
    });
    //监听事件,实时更新,而不是手动刷新浏览器更新。对应智能合约中自定义的event事件
    var infoEvent = simple.Instructor();
    infoEvent.watch(function(error,result){
        if(!error){
            $("#loader").hide();
            $("#info").html(`我叫` + result.args.name + `, 我今年` + result.args.age + `岁了。`);
        }else{
            $("#loader").hide();
            $("#info").html("Error:" + error);
        }
    })
    
    

    结语

    这是一个简单的Dapp开发示例,目的是熟悉以太坊Dapp开发流程。
    此方式有个很大的缺点,就是web3与智能合约交互太麻烦,修改智能合约后需要手动修改abi和地址信息。而且也不容易测试。

    实际开发Dapp都是使用truffle框架来开发。后续会写truffle开发示例。

    相关文章

      网友评论

          本文标题:第一个去中心化应用

          本文链接:https://www.haomeiwen.com/subject/yusxhqtx.html