阿里云BaaS下蚂蚁区块链开发实践(一)

蚂蚁链与阿里云

  蚂蚁区块链是蚂蚁金服自主开发联盟区块链底层引擎,在阿里的强力宣传下,一直保持很高的曝光度。特别是今年的双十一,给4亿件天猫海淘商品在区块链上获得了“身份证”,实现从海外采购到国内配送的全链路溯源。蚂蚁链经过阿里内部这么多极端应用场景的锤炼,相信可以胜任大多数的企业应用场景。
  蚂蚁链目前暂时还未开源,无从了解过多的技术细节。不过经过公开的文档中可以看到底层采用的是以太坊那套技术框架,虚拟机采用的是EVM,智能合约开发使用Solidity,提供Java与JS SDK。

  蚂蚁链也是阿里云BaaS服务支持的三大区块链引擎之一,使用阿里云BaaS,可以极大简化区块链网络的部署运维成本。当然,蚂蚁链目前没有开源,也不提供独立部署,只能通过阿里云BaaS或是蚂蚁金服下的区块链BaaS平台来进行管理。
  除了运维的支撑,阿里云BaaS也为蚂蚁链提供一个在线合约开发工具 – “Cloud IDE”。有点类似于以太坊的Remix IDE,为智能合约开发提供简单、高效的集成环境,并提供以下核心功能:

  • 合约编辑与编译,展示编译结果字节码和接口说明(ABI)。
  • 合约的部署和调用;提供默认体验链环境和测试账户,用来部署和调用合约。
  • 解析合约方法的返回值、事件日志等,辅助调试合约;
  • 保存合约工程到 BaaS 合约工程管理。

在前段时间,我有机会体验了阿里云BaaS服务,尝试照着文档开发了一个蚂蚁链的Demo应用。现把主要的开发步骤与心得记录下来,与大家共享。

创建蚂蚁链网络

通过BaaS可以很方便创建联盟,建立区块链网络,详细操作可以参考阿里云官方文档或我的上一篇博客。

蚂蚁链智能合约

蚂蚁链虽使用solidity作为智能合约的开发语言,但使用时与以太坊最新原生的solidity语法有不少差别:

  1. 蚂蚁链只支持到solidity 0.4.23及以下版本,不支援solidity最新的语法特性;
  2. 由于蚂蚁区块链对 Solidity 语言的支持与原生的 Solidity 语言不同,因此不能使用外部社区的 solc-js 编译工具。只能使用BaaS 平台提供的 专用solc-js
  3. 蚂蚁区块链合约平台基本支持 Solidity 所有的数据类型,但是对于一些用户编写的合约的输入参数类型并没有完全的支持,比如参数输入中二维数组的输入。
  4. 蚂蚁区块链合约平台提供了 identity 类型来标注每一个用户的身份,不支持原生 Solidity 中的 address 类型,identity 的长度为 32 字节。
  5. 蚂蚁区块链也提供了一些合约中的原生函数,具体可参考阿里云文档

Demo 功能介绍

我实现的Demo主要目标是建立一套简单的产品溯源系统,模拟对产品从商家生产、物流运输到最终商场销售进行全流程查询与追踪。
Demo中主要包含以下角色与功能:

  1. 生产商:manufacturer
    • 创建产品
    • 创建批次
    • 创建批次
    • 创建订单
    • 查询订单状态
    • 产品批次溯源
  2. 运输商:transporter
    • 运送订单
    • 签收订单(中途站)
    • 记录订单途经位置
  3. 零售商:retailer
    • 签收订单
    • 更新库存
    • 查询库存
    • 售出产品
    • 查询售出记录
    • 产品批次溯源
  4. 管理员:admin
    • 创建用户,设置用户角色
    • 查询用户及其角色

合约实现

由于蚂蚁链合约开发语言与原生solidtiy有一定的差异,使用原生的solcjs编译会出各种问题,并且错误提示也不完整。因此强烈建议使用阿里云Cloud IDE开发合约。使用方法是在“联盟管理”中可以看到“合约工程管理”,然后新建或编辑现有合约工程即可。
阿里云BaaS下蚂蚁区块链开发实践(一)_第1张图片

  1. 创建所需的枚举与结构体
    //用户角色
    enum UserRole {
        manufacturer,
        transporter,
        retailer,
        admin
    }

    //订单状态
    enum OrderState {
        created,
        transporting,
        finished
    }

    //用户结构体
    struct User {
        identity account;
        string name;
        UserRole role;
        string companyName;
        string companyAddress;
    }

    //产品结构体
    struct Product {
        string name;
        string modelNumber;
        string manufacturerName;
        string description;
    }

    //批次结构体
    struct Batch {
        string batchNumber;
        string modelNumber;
        uint32 quantity;
        uint256 timestamp;
    }

    //订单结构体
    struct Order {
        string orderNumber;
        string manufacturerName;
        string retailerName;
        OrderState state;
        string batchNumber;
        string modelNumber;
        uint32 quantity;
        uint256 timestamp;
    }

    //订单状态
    struct OrderStatus {
        string orderNumber;
        OrderState status;
        uint256 timestamp;
        string userAccount;
        string companyName;
        string companyAddress;
    }

    //库存结构体
    struct Inventory {
        string batchNumber;
        string modelNumber;
        string orderNumber;
        uint64 quantity;
        uint256 timestamp;
    }

    //销售记录
    struct SaleRecord {
        string batchNumber;
        string modelNumber;
        uint64 quantity;
        uint256 timestamp;
        string userAccount;
    }

    //订单状态
    struct MyOrderStatus {
        mapping(uint => OrderStatus) statusList;
        uint statusSize;
    }

    //销售历史清单
    struct MySoldList {
        mapping(uint => SaleRecord) saleRecordList;
        uint soldSize;
    }
  1. 定义管理员,将发布合约的用户定义为管理员,管理员可以设置分配其他用户权限
identity admin; 
constructor() public{
        admin = msg.sender;
}

// modifier
modifier onlyAdmin() {
    require(msg.sender == admin,"Permission denied");
    _;
}
  1. 添加管理员相关方法
    //添加或设置用户基本信息
    function setUser(identity _account, string _name, uint256 _role, string _companyName, string _companyAddress) public onlyAdmin returns(bool) {
        userList[_account] = User(_account, _name, UserRole(_role), _companyName, _companyAddress);
        return true;
    }
    //获取用户基本信息
    function getUser(identity _account) public onlyAdmin returns(identity, string, UserRole, string, string) {
        var user = userList[_account];
        return (user.account, user.name, user.role, user.companyName, user.companyAddress);
    }
  1. 为其他用户添加业务方法
    //添加产品
    function AddProduct(string _name, string _modelNumber, string _description) public returns(bool) {
        var user = userList[msg.sender];
        productList[_modelNumber] = Product(_name, _modelNumber, user.companyName, _description);

        return true;
    }
//其他省略 ...

一点感受

蚂蚁链不支持最新的solidity语法,开发起来会有些不方便。使用Cloud IDE开发可以快速编译、检查代码问题,并且能直接发布到测试网络上进行测试,确实能提高效率。
另一个需注意的地方是,蚂蚁链不支持address类型,取而代之是identity类型,从msg.sender中取出也就是当前用户的identity数据。
蚂蚁链的用户体系需要先在BaaS中创建,每个用户有一个用户名。合约中无法使用用户名,只能使用identiyt。而identity就是这个用户名的hash结果,可以通过SDK中辅助工具类中getHash方法,将用户名转成identity. 如
Chain.utils.getHash('Tester001') //通过账户 name,计算得到账户的 identity
完整Demo代码请参考:https://github.com/ft-john/antblockchain_demo

你可能感兴趣的:(区块链)