区块链原理与技术期末项目实验报告

Github: https://github.com/Alva112358/BlockChain


一、项目简介


       项目的选题为去中心化的手机交易平台,其实就是一个去中心化的网店。选择这个项目其实还是有考虑的,毕竟区块链的特点是去中心化的分布式系统,而且具有很好的数据隐秘性,因此利用区块链的这一特点,能够在网络交易平台上实现一些很好的应用。
       当下像淘宝、京东等线上交易平台都有一个特点,就是他们都是中心化的交易系统,在客户和店家之间进行交易时,需要有一个可信任的第三方用户进行中介,以确保交易的可靠性。虽然当前第三方交易平台的发展前景非常好,客户的满意度也非常高,但是毕竟还是存在隐秘的风险,而且更多的小平台存在的风险也越大,因此发展一个去中心化的交易平台,就能够增加交易的可靠性,而且也是中小企业网络交易平台发展的方向。
       本项目的实际环境是一个手机交易平台,利用智能合约进行编程。合约由店主发起,当用户挑选到自己喜欢的手机的时候,就能够提交订单,此时合约内部就能够收到客户订单中的手机数目和手机类型,从而将客户中扣除相应的以太币到合约内部,而不是直接交易给店家。店家只有将货给到物流,物流公司确认买家发货,并且买家最终确定收货以后,钱才能够从合约中扣除交给店家。整个过程中没有第三方中介的参与,实现去中心化。


二、测试环境


       项目的测试的操作系统为mac OS,使用truffle框架进行实现,使用Ganache在私有链上进行测试。truffle是目前流行的以太坊开发框架,支持智能合约的编译、部署和测试,本项目属于一个开发学习项目,因此在私有链上进行测试。相应配件的版本如下所示:

    truffle -v5.0.0
    node -v11.4.0
    npm -v6.4.1     

       由于Github文件大小的限制,在上传的时候将node_modules文件夹删除,因此在运行项目前先在当前目录下执行下列语句:

    npm install

       如果依然缺某些modules,则需要自行npm进行安装即可。


1. Ganache-cli的配置和使用

       项目文件夹为DApp,运行的方法为在DApp目录下开启两个终端,首先在第一个终端上输入如下命令,在Ganache上创建一个私有链:

    ganache-cli -e 3001 -l 99999999999999 -g 20000

       需要注意的是,如果未安装Ganache,需要在终端下先运行:

    sudo npm install -g ganache-cli

       本次实验没有用Ganache-cli的图形化界面,只是在终端上运行,启动后,显示的界面如下图所示:

)
       为了方便测试,设置初始以太币为3000,同时由于在测试过程中发现的一些gas的限制问题,因此将gas的限制设置为一个很大的数。私钥可以用于在metamask等插件中进行账户的部署,本实验没有用到。当然在使用的过程中,可能会由于系统缺乏某些nodejs的安装包而无法启动,需要缺乏哪些就用npm进行安装即可。


2. truffle的配置和使用

       首先是truffle的安装,truffle的安装只需要在终端中输入下列指令即可:

    sudo npm install -g truffle

       需要注意的是,truffle的安装过程在不同的系统中可能会造成失败,这只能在网上找到相应的错误,因为错误的分析实在过于繁杂。
       由于已经是完整的项目,因此truffle工程的创建过程在此处省略,只显示使用的方法。首先需要对智能合约进行编译,输入如下命令:

    truffle compile --all

       命令输入后应该会得到如下图所示:

       然后就需要将合约部署到私有链上,需要在终端输入如下命令:

    truffle migrate --reset

       命令输入后应该会得到如下图所示:

       同时在运行Ganache-cli的终端上,应该会输出如下信息:

       最后就是运行智能合约,输入如下指令:

    npm run dev

       运行指令后会得到如下图所示的界面:

       需要注意,在上图中中项目的运行端口为http://localhost:8083/,具体的端口号需要根据运行时输出的端口号,在谷歌浏览器上访问相应的端口,即有可能为8080,8081,8082等,需要特别注意。
       这时候,打开谷歌浏览器,输入localhost:8083就可以访问到项目的Web页面。注意需要先将谷歌浏览器的Metamask插件关闭,否则会有不知名错误。最后得到的Web页面如下所示:


二、实验测试


1. 智能合约的测试

       智能合约的初步测试可以在Remix上对智能合约的函数进行测试,Remix上拥有初始化的账户,可以对某些函数进行简单的测试,这样可以避免智能合约部署到以太坊时,某些函数出现问题而造成以太币的损失。智能合约在Remix上的测试在合约部署阶段已经完成,因此在此处不再累述。合约的Solidity代码如下所示:

pragma solidity ^0.5.0;

contract computerShop {

    // Use to finish the transaction.
    enum States { NOTHING, ORDERING, SENDING }
    // The shop's keeper.
    address public owner;

    // The computers.
    mapping(bytes32 => uint) public computers;

    // State
    States purchase_state;
    // Constructor, open a new computer shop.
    constructor() public {
        // Initialize the computers.
        computers["iPhone"] = 500;
        computers["Sumsung"] = 350;
        computers["HUAWEI"] = 390;

        purchase_state = States.NOTHING;
    }

    // Get specific computer's price.
    function get_price_by_name(bytes32 _name, uint number) public view returns (uint) {
        return computers[_name] * number;
    }

    // Buyers order a computer.
    function ordering(uint money) public payable {
        require (purchase_state == States.NOTHING, "NOT NOTHING");
        require (msg.sender != owner, "NOT BUYER");
        require (msg.sender.balance >= money, "NOT ENOUGH MONEY");

        purchase_state = States.ORDERING;
    }

    // Owner send the computer.
    function sending() public {
        require (purchase_state == States.ORDERING, "NOT ORDERING");
        require (owner == msg.sender, "NOT SELLER");

        purchase_state = States.SENDING;
    }

    // Buyers comfirm.
    function comfirm() public {
        require (purchase_state == States.SENDING, "NOT SENDING");
        require (msg.sender != owner, "NOT BUYER");
        
        purchase_state = States.NOTHING;
    }

    function withdraw() public payable {
        require (msg.sender == owner, "NOT SELLER");
        require (purchase_state == States.NOTHING, "NOT NOTHING");
        msg.sender.transfer(address(this).balance);
    }

    function check_balances() public view returns (uint) {
        require (owner == msg.sender, "NOT OWNER");
        return address(this).balance;
    }

    function get_status() public view returns (uint) {
        if (purchase_state == States.NOTHING) return 1;
        if (purchase_state == States.ORDERING) return 2;
        if (purchase_state == States.SENDING) return 3;
    }

    function getBalance() public view returns(uint) {
        return msg.sender.balance;
    }
    
    function sellerInit(address addr) public {
        owner = addr;
    }
}


2. 在Web端进行测试

       在Web端的测试,首先是用户购买其中自己喜欢的商品的流程(本项目指定第0个账户为合约的发起者):


客户选购自己喜欢的手机

       切换至客户1,购买相应数量的iPhone,结果图如下所示:

       同时店主的余额此时并没有立刻增加,而是先转账给合约进行冻结,等待客户确认,手机店的购买信号由NOTHING转换为ORDERING,此时店主可以确认购买信息,如下图所示:


店主确认发货

       此时只有店主可以确认发货,等待客户确认收货,但是店主不能够确认收货,如果此时店主点击确认收货,就会报错,如下图所示:

       当正确点击确认发货后,手机店销售状态由ORDERING转为SENDING,如下图所示:


客户确认收货

       此时客户就能够确认收货了,当客户确认收货后,钱就能够从合约中调出,转账给店主,店的状态由SENDING转为NOTHING,此时客户可以再次购买商品,确认收货,确认后显示的信息如下所示:

       此时切换到店主账户,可以发现店主余额增加了1000,说明交易成功,如下图所示:

防止余额不足时超额购买

       如果想购买的手机的总价格超过了自己所拥有的钱,那么就会报错,如下图所示:


三、项目可拓展部分


       由于这次作业时间比较紧凑,所以实现的功能非常简陋,也只是简单实现了界面,结合上次的智能合约的编程作业,而且因为学习过程占用了大量时间,因此也删去了部分功能,后续可以对这个项目作出的改进有如下几点:

1. 客户购买信息回溯

       客户在同一家店可能会购买多次物品,而区块链本身具有回溯和信息隐秘性的功能,因此可以实现一个客户查询购买信息的功能,特定的客户只能查询特定的资料。


2. 店主入货加货

       由于时间比较紧凑,因此没有实现这个功能,其实这个功能还是比较简单的,只需要简单修改智能合约的内容即可。


3. 登录界面完善

       本项目的登录界面简单至极,因此方便测试,其实可以用Vue等框架写一个简单的交互界面,可能会更加友善,加一个服务器和数据库,就能成为比较完善的项目了。


4. 多用户并发购买

       这个项目的功能比较简单,只能够实现单用户交易,其他用户如果想要购买手机的话就需要排队,因此在后续的补充中可以加入并发操作。


四、实验心得


       本次实验是区块链智能合约编程的一次实战,由于以前的课程和课程内容上都很少接触智能合约的编程,因此在实战的过程中遇到了非常非常非常多的问题。以前都只是听说过区块链这个名词,没有听说过Solidity,以太坊这些概念,而且网上的资料也是非常少,基本上都是入门教程,所以就更加困难了。
       首先最困难的莫过于搭建环境了,第一次搭建环境是用的Windows操作系统,在truffle的安装和初始化过程中就遇到了许多问题,后来就放弃了用Windows。然后就是用Linux虚拟机进行实验,但是同样在truffle安装过程中不停报错,而且错误也很难找到,曾经想过不用框架,但是想到为这个框架学了那么多东西,还是决定换mac OS进行实验,幸运的是,在mac OS上整个安装过程非常顺利,运行过程也很顺利。
       然后就是Web前端和web3js的一些编程,智能合约在上次作业中已经大概写好了,因此只是对智能合约进行简单的修改,主要是web3js调用智能合约函数的过程比较费劲,也学了很多东西,搞着搞着还是搞出来了。但是这个项目的功能非常简陋,只有简单的下单、确认和收货功能,但是蕴含在其中的努力还是很多的,花了整整4天来做这个项目。


附录

项目源代码:Github

posted @ 2019-01-18 14:38  Alva112358  阅读(1912)  评论(0编辑  收藏  举报