[toc]

一、产品简介

1、 产品概述

DMA开放平台基于亦来云基础服务支持,将支付,智能合约,数据存储,数据营销通过接口的形式开放给第三方合作伙伴,帮助第三方合作伙伴快速创建具有区块链特性的应用。

2、 产品优势

通过接入DMA平台,开发人员无需详细了解区块链的工作原理,就能基于亦来云主链、DID侧链、ETH侧链开发去中心化应用。

3、 功能特性

通用型移动APP钱包,现支持ELA 主链钱包、DID侧链钱包、ETH侧链钱包

去中心化存储

合约模板丰富,包含ERC20合约模板、ERC721合约模板,ERC721模板中有 收费类模板,质押类模板、N元购模板、票券销售类模板等

4、 应用场景

4.1 区块链钱包

拥有一个区块链数字货币钱包,便象征着迈进区块链领域的大门。区块链去中心化特点可省去第三方中介环节,实现点对点的对接,在大大降低成本的同时,快速完成交易支付。

Elastos DMA 提供完善的Wallet(钱包)API服务。是对Wallet模块的封装,包含以太坊钱包功能封装、亦来云钱包封装。包含各类钱包创建,导出,查询余额,转账交易等。

4.2 发布纪念币

使用ERC721合约发布的资产具有不可置换性,你可以赋予每个token独一无二的属性,开发者们可以开发一个纪念币相关的dApp。将值得纪念事情记录下来,发布你的专属纪念币。

4.3 票务应用

ElastosDMA团队自主开发了ElastosDMA平台上的第一家去中心化电子商务体验商店——uptick。是一个由可信商家参与的,为设计师提供分账的,去中心化的电子商务dAPP,并将售卖商品的范围限定在精致的、有版权设计的一手文创类产品。

4.4 收费类活动应用

收费类活动主要用于小型活动,活动类型为收费类活动,交易过程中用户支付的报名费用暂时存在托管合约作为质押,当会议举行时,现场经过举办方验票之后,费用才能进入举办方账户。

4.5 质押类活动应用

质押活动,用户支付的费用暂时存在托管合约,当用户验票之后,用户报名活动的费用会退还到用户钱包,如果用户在活动结束前一直没有验票,此部分的报名费通过合约设置可归举办方所有或守约人均分。

5、基础术语

名词 说明
智能合约 Smart Contract 一种旨在以信息化方式传播、验证或执行合同的计算机协议。一个智能合约是一套以数字形式定义的承诺(promises),包括合约参与方可以在上面执行这些承诺的协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。
私钥 Private key 私钥是一组64位的16进制字符,通过私钥我们能够访问一个账户。用户需要保存好自己的私钥。
GasLimit 该交易的执行时使用gas的上限
GasPrice 交易发送者愿意支付的gas费用的价格。一个单位的gas表示了执行一个基本指令,例如一个计算步骤。
地址 address 钱包账户地址
助记词 Mnemonic 助记词由12-24个单词组成,助记词可以生成私钥。一个助记词可以生成无穷个私钥,可以理解成助记词是个树的根,这个根上可以长很多分支,每个叶子是一个私钥,Cobo钱包不同币种用的是不同的分支。这也是为何一个助记词可以管理HD账户下所有的钱包地址。
随机数 nonce 用于维护以太坊交易的随机数
交易 Transaction 区块链上的一个事务请求,用来承载具体业务操作数据的结构。区块链上所有针对世界状态的变化操作均是基于交易来完成的。
交易哈希 Transaction hash 交易上链成功后,产生的唯一哈希值。
交易回执 Transaction receipt 是交易的执行结果。区块链是异步的系统,交易执行后需要共识,与传统架构不同,不能直接返回交易执行是否成功,因此需在回执中查看最终交易结果。
节点信息 Node information 区块链节点的相关信息。一个区块链一般由多节点组成。
区块 Block 区块链上存储打包交易数据以及交易执行结果数据的一种组织形式。区块彼此之间通过前向的应用彼此链接形成区块链。 每个区块记录着上一个区块的哈希值、本区块中的交易集合、本区块的哈希等基础数据。
区块高度 Block height 区块高度,简称块高,用来识别区块在区块链中的位置,并据此找到和这个区块相关的所有基础属性和交易记录。
区块链技术 Blockchain 也被称之为分布式账本技术,是一种去中心化的分布式数据库技术,其特点是去中心化、公开透明、不可篡改、可信任。区块链的每笔数据,都会广播全网的区块链节点,每个节点都有全量的、一致的数据。
去中心化应用 Decentralized applications(DApp) 与传统中心化应用的主要区别是,DApp 通过客户端直接连接区块链节点,通过智能合约计算和访问数据,没有中心化的后端服务。
燃料 Gas 智能合约在虚拟机中执行计算和存储的消耗度量,通过燃料可防止一些恶意攻击和计算、存储的浪费。

二、发布说明

2018.12.31 DMA 测试版

2019.6.30 DMA 稳定版 更新了钱包SDK,Carrier离线消息

三、用户指南

1、JAVA SDK 开发指南

1.1 SDK说明

平台JAVA SDK 是通过服务(Service)的形式对外提供功能,具体包括资产管理服务(AssetManagement )个人数据服务(Passport)存储服务(Storage)钱包服务( Wallet)商户服务 ( Merchant),消息服务( Message),工具类( Utility) 。

运行环境说明
  • JDK 8 及以上版本在终端运行 java -version 查看当前 Java 版本。
  • Maven 3.5.4 及以上版本在终端运行 mvn -v 查看当前 Maven 版本。

1.2 快速开始

步骤一:在Maven文件中引入SDK包

  • 安装下载的 jar 包到本地仓库。
  • 从命令终端进入到下载的文件根目录,执行以下命令:
//安装 SDK 到本地仓库
mvn install:install-file -Dfile=dma-base-2.1.4-eth-beta.jar -DgroupId=org.elastos -DartifactId=dma-base -Dversion=2.1.4-eth-beta -Dpackaging=jar

mvn install:install-file -Dfile=dma-service-2.1.4-eth-beta.jar -DgroupId=org.elastos -DartifactId=dma-service -Dversion=2.1.4-eth-beta -Dpackaging=jar

mvn install:install-file -Dfile=dma-utility-2.1.4-eth-beta.jar -DgroupId=org.elastos -DartifactId=dma-utility -Dversion=2.1.4-eth-beta -Dpackaging=jar

步骤二:使用 Intellij IDEA 创建一个基于 Maven 构建的空项目(Demo)。

步骤三:导入依赖


<repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>

    <dependencies>

        <dependency>
            <groupId>org.elastos</groupId>
            <artifactId>dma-base</artifactId>
            <version>2.1.4-eth-beta</version>
        </dependency>
        <dependency>
            <groupId>org.elastos</groupId>
            <artifactId>dma-service</artifactId>
            <version>2.1.4-eth-beta</version>
        </dependency>

        <dependency>
            <groupId>org.elastos</groupId>
            <artifactId>dma-utility</artifactId>
            <version>2.1.4-eth-beta</version>
        </dependency>

        <dependency>
            <groupId>com.github.ipfs</groupId>
            <artifactId>java-ipfs-api</artifactId>
            <version>v1.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.elastos</groupId>
            <artifactId>wallet.lib</artifactId>
            <version>0.0.9</version>
        </dependency>
    </dependencies>



1.3 接口调用说明

AssetManagement模块

AssetManagement模块基于ETH侧链,资产分为ERC20类型资产和ERC721类型资产

  • ERC20资产管理类构建
    @Test
    public void ERC20Test() {
        String nodeUrl = "http://127.0.0.1:8545";//节点地址
        Token20 token20 = new Token20Service(nodeUrl);
    }


  • ERC721资产管理类构建
    @Test
    public void ERC721Test() {
        String nodeUrl = "http://127.0.0.1:8545";//节点地址
        Token721 token721 = new Token721Service(nodeUrl);
    }

Merchant模块

Merchant模块中有三种不同类型的实现。MerchantService接口实现ERC721资产以售卖形式进行资产的流通;ChargeActivityService接口以收费活动形式进行资产的流通;PledgeActivityService接口以质押活动形式进行资产的流通。

  • MerchantService

    @Test
    public void merchant() throws TokenException, RpcException {
        String nodeUrl = "http://127.0.0.1:8545";//ETH链节点地址
        String chainType = "";//链类型(自定义)
        //创建MerchantService
        MerchantService merchantService = new MerchantServiceImpl(chainType, nodeUrl);

        String privateKey = "";//用户私钥
        BigInteger gasPrice = BigInteger.valueOf(1000000000);//gas费用
        BigInteger gasLimit = BigInteger.valueOf(7000000);//gas限制
        String name = ""; //ERC721资产名称
        String symbol = ""; //ERC721资产标识
        String metadata = "";//ERC721资产信息(自定义)
        //创建合约
        JsonResult<DeployResult> jsonResult = merchantService.deploy(privateKey, gasPrice, gasLimit, name, symbol, metadata);

        System.out.println(jsonResult.getData().getAssetAddress());//资产合约地址
        System.out.println(jsonResult.getData().getTrustAddress());//资产托管合约地址

    }

  • ChargeActivityService
    @Test
    public void chargeActivityService() throws TokenException, RpcException {
        String nodeUrl = "http://127.0.0.1:8545";//ETH链节点地址
        String chainType = "";//链类型(自定义)
        //ChargeActivityService
        ChargeActivityService chargeActivityService = new ChargeActivityServiceImpl(chainType, nodeUrl);

        String privateKey = "";//用户私钥
        BigInteger gasPrice = BigInteger.valueOf(1000000000);//gas费用
        BigInteger gasLimit = BigInteger.valueOf(7000000);//gas限制
        String name = ""; //ERC721资产名称
        String symbol = ""; //ERC721资产标识
        String metadata = "";//ERC721资产信息(自定义)
        Long endTime = 1568876617L;//活动结束时间
        //创建合约
        JsonResult<DeployResult> jsonResult = chargeActivityService.deploy(privateKey, gasPrice, gasLimit, name, symbol, metadata, endTime);

        System.out.println(jsonResult.getData().getAssetAddress());//资产合约地址
        System.out.println(jsonResult.getData().getTrustAddress());//资产托管合约地址

    }

  • PledgeActivityService
    @Test
    public void pledgeActivityService() throws TokenException, RpcException {
        String nodeUrl = "http://127.0.0.1:8545";//ETH链节点地址
        String chainType = "";//链类型(自定义)
        //PledgeActivityService
        PledgeActivityService pledgeActivityService = new PledgeActivityServiceImpl(chainType, nodeUrl);

        String privateKey = "";//用户私钥
        BigInteger gasPrice = BigInteger.valueOf(1000000000);//gas费用
        BigInteger gasLimit = BigInteger.valueOf(7000000);//gas限制
        String name = ""; //ERC721资产名称
        String symbol = ""; //ERC721资产标识
        String metadata = "";//ERC721资产信息(自定义)
        Long endTime = 1568876617L;//活动结束时间
        //创建合约
        JsonResult<DeployResult> jsonResult = pledgeActivityService.deploy(privateKey, gasPrice, gasLimit, name, symbol, metadata, endTime);

        System.out.println(jsonResult.getData().getAssetAddress());//资产合约地址
        System.out.println(jsonResult.getData().getTrustAddress());//资产托管合约地址

    }

Passport模块

Passport模块基于亦来云DID侧链

    @Test
    public void passportService() {
        String didNodeUrl = "http://127.0.0.1:20336";//did侧链节点地址
        PassportService passportService = new PassportServiceImpl(didNodeUrl, "");
        DIDAccount didAccount = passportService.create(HdSupport.MnemonicType.ENGLISH);
        System.out.println(didAccount.getPrivateKey());//私钥
        System.out.println(didAccount.getMnemonic());//助记词
        System.out.println(didAccount.getAddress());//did钱包地址
        System.out.println(didAccount.getDid());//did
    }


Storage模块

Storage模块基于ipfs实现

    @Test
    public void IpfsService(){
        String multiaddr = "/ip4/127.0.0.1/tcp/5001";
        IpfsService ipfsService= IpfsService.getInstance(multiaddr);
    }

Wallet模块

Wallet模块是对用户钱包的管理,针对不同的链,有不同的实现。目前主要有基于ETH链的EthWalletService;基于ELA链的ElaWalletService;基于ETH侧链的ElaETHSideWalletService;基于DID侧链的ElaDIDSideWalletService。用户根据自己的需要,选择不同的实现类。

1.4 API说明

2、Android SDK 开发指南

2.1 SDK说明

平台Android SDK 是通过服务(Service)的形式对外提供功能,具体包括资产管理服务(AssetManagement )个人数据服务(Passport)存储服务(Storage)钱包服务( Wallet)商户服务 ( Merchant),消息服务( Message),支付服务(Payment)工具类( Utility) 。SDK 提供以同步或异步方式发送交易、查询交易等的接口。无论以同步或异步的方式发送交易,SDK 封装了发送交易后查询收据的逻辑,以便您查看交易的执行结果。

2.2 快速开始

集成和开发,本项目SDK使用AAR的打包方式

步骤1:下载DMA客户端SDK

包含DMA_BASE、DMA_SERVICE、DMA_MESSAGE、DMA_utility

步骤2:导入SDK

步骤3:在主项目的 build.gradle 中,添加下面的内容,将 libs 目录作为依赖仓库:

allprojects {

    repositories {
    // 添加下面的内容
    flatDir {
        dirs 'libs'
    }

    // ... jcenter() 等其他仓库
}
}

步骤4:在您 App Module 的 build.gradle 中,添加下面的内容,将DMA SDK 作为项目依赖:

dependencies {

// 添加下面的内容
api 'org.elastos:carrier:5.4.0'

implementation 'org.elastos:ElastosSdkWallet:v0.1.20@aar'

api 'org.web3j:core:3.3.1-android'

api ('org.elastos:dma-utility:1.1.4-eth-beta'){

exclude group: 'org.web3j'

exclude group: 'org.bouncycastle'

}

implementation(name: 'Elastos.DMA.Base1.0.0', ext: 'aar')

implementation(name: 'Elastos.DMA.Service1.0.0', ext: 'aar')

implementation(name: 'Elastos.DMA.Message1..0.0', ext: 'aar')

    // ... 其他依赖项
}

至此,DMA SDK 开发资源导入完成。

步骤5:添加运行权限

为正常完成良好的体验,DMA SDK 需要使用下面这些权限:

android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE

您需要在 AndroidManifest 里配置以上 3 个权限,DMA SDK 在运行时需要进行网络连接,并在必要的时候判断网络连接的状态(4G/Wi-Fi)等来进行应用体验的优化。

2.3 接口调用说明

初始化节点信息
  public static String didip = "http://54.64.220.165:21604";//测试DID 
public static String elaip = "http://54.64.220.165:21334";//测试ELA
public static String ip = "http://47.105.136.158:8545";//DMAtestlink
public static String ipfsIP="http://47.105.136.158:8080";//ipfs生产
private volatile static EthWalletService ethWalletService;
    /**
    *初始化钱包服务
    **/
    public static EthWalletService getClient() {
    if (ethWalletService == null) {
        ethWalletService = new EthWalletService(ip);
    }
    return ethWalletService;
}

需要在新线程中调用接口(可参考 demo 实现)

示例代码:
private void verifyWallet(String pwd){
new AsyncTask<Void, Void,  Passport >(){
@Override
protected  Passport doInBackground(Void... params) {
   Passport passport= passportService.create(HdSupport.MnemonicType.ENGLISH,"");
    return passport;
}
protected void onPostExecute( Passport  passport) {
         System.out.println(passport.getMnemonic());
   System.out.println(passport.getId
());
//根据DID产生的助记词,导出ETH钱包
EthAccount ethAccount=NodeClient.getClient().exportByMnemonic(passport.getMnemonic());
//根据DID产生的助记词,导出ELA钱包
ElaWallet elaWallet= NodeClient.getHdWallet(TestActivity.this,words);

};
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

2.4 接口测试

首先根据选择测试的链,调用对应的创建钱包账户接口,创建无需准备对应的货币

ELA主链 转账交易transfer()测试需要ELA主链币

DID链,写入数据passport.setInfo() 需要准备DID侧链币,可通过主链充值的方式,也可以通过其他钱包转账的方式

ETH侧链,转账交易transfer(),合约发布deploy(),发布资产mint() 资产上架onSales() 资产下架 offSales() 创建订单createOrder() 等链上交易接口需要准备测试币

2.5 API详细说明

3、IOS SDK 开发指南

3.1 SDK说明

平台Android SDK 是通过服务(Service)的形式对外提供功能,具体包括资产管理服务(AssetManagement )个人数据服务(Passport)存储服务(Storage)钱包服务( Wallet)商户服务 ( Merchant),消息服务( Message),支付服务(Payment)工具类( Utility) 。SDK 提供以同步或异步方式发送交易、查询交易等的接口。无论以同步或异步的方式发送交易,SDK 封装了发送交易后查询收据的逻辑,以便您查看交易的执行结果。

3.2 快速开始

#Swift: 5.0 以上

1 -- 先使用Carthage

在文件中添加如下

github "tang3680564/DMASDK" "master"

执行命令

Carthage update --platform ios

2 -- 再使用 pod

在文件中添加如下

pod 'ElastosCarrierSDK', '~> 5.3.2'

执行命令

pod install

最后将 carthage 的 build 里面的 framework 和 lib目录中的ElastosSdkWallet.framework ,ElastosSdkKeypair.framework添加到项目当中

builsetting: bitcode -> false

在使用的地方使用

import DMASDKV1

3.3 接口调用说明

1.钱包相关:现在支持 eth,ela,did三个钱包

生成eth钱包:

///创建 eth 钱包服务

let ethService : EthService = EthService();

///生成(助记词,私钥,地址,)

let result = ethService.create()

///助记词

let mnemonic = result.0

///私钥

let privateKey = result.1

///地址

let address = result.2
查询余额
///节点地址

let url = ""

///创建 eth 钱包服务

let ethService : EthService = EthService(url : url);

///查询地址

let address = ""

///查询余额

let balance = ethService.balances(address:address)

2存储相关

1.上传
///ipfs节点地址,例如:"47.105.136.158"

let url = ""

///上传节点端口,例如:8080

let serverPost = ""

///创建 ipfs 服务

let ipfs = IpfsService(URL : url,serverPost : serverPost)

///上传,data 数据

let data = Data()

///上传返回凭证

let hash = ipfs.add(fileData : data)
2.下载
///ipfs节点地址,例如:"47.105.136.158"

let url = ""

///下载节点端口,例如:5001

let serverPost = ""

///创建 ipfs 服务

let ipfs = IpfsService(URL : url,serverPost : serverPost)


///上传返回的凭证

let hash = ""

///下载

let arrary = ipfs.getBytes(hash:hash)

3.资产相关

1.ChargeActivityService(收费活动模板)
发布合约
///eth的节点地址

let url = ""

///创建服务

let chargeActivityService = ChargeActivityService(url : url)
let privateKey = ""
let gasPrice = defaultGasPrice
let gasLimit = defaultGasLimit
let name = ""
let symbol = ""
let metadata = ""
let endtime = "\(Int(Date().timeIntervalSince1970) + 3600 * 24)"
/// - Parameters:
    ///   - privateKey: 私钥
    ///   - gasPrice: gasPrice description
    ///   - gasLimit: gasLimit description
    ///   - name: 合约名称
    ///   - symbol: 合约简介
    ///   - metadata: 合约描述
    ///   - endtime: 活动结束时间
    /// - Returns: assetAddress : 资产合约地址,platformAddress : 托管合约地址
    let result = chargeActivityService.deploy(privateKey:privateKey,gasPrice:gasPrice,gasLimit:gasLimit,name:name,symbol:symbol,metadata:metadata,endtime : endtime)
初始化资产
///eth的节点地址

let url = ""

///创建服务

let chargeActivityService = ChargeActivityService(url : url)

let privateKey = ""
let contractAddress = ""
let toAddress = ""
let tokenArr : NSMutableArray = [1000]

 /// 批量创建资产
    ///
    /// - Parameters:
    ///   - privateKey: 私钥
    ///   - assetAddress: 资产合约地址
    ///   - to: 资产归属地址
    ///   - array: 资产 id 数组
    ///   - metaData: 资产描述
    ///   - isTransfer: 是否可以转送
    ///   - isBurn: 是否可以销毁
    ///   - gasLimit: gasLimit description
    ///   - gasPrice: gasPrice description
    /// - Returns: return value description

let reult = charge.mintWithArrayGas(privateKey : privateKey,assetAddress : contractAddress,to: toAddress, array: tokenArr as! Array<Any>, metaData: "", isTransfer: true, isBurn: true)

3.4 API详细说明

四、常见问题

五、错误码

    SUCCESS | 0 | 操作成功
ERROR | -1 | 请求失败
PARAMS_ERROR | 2 | 参数错误
SYSTEM_ERROR | 4 | 系统异常

IO_ERROR | 29 | 远程调用失败
REVOKE_ERROR | 72 | 下架失败
ON_SALE_ERROR | 73 | 上架失败
CONFIRM_ORDER_ERROR | 92 | 下单失败

CREATE_ORDER_ERROR | 96 | 创建订单失败
PAYMENT_MERCHANT_REGISTERED | 116 | 已注册
WALLET_ADDRESS_EMPTY | 117 | 钱包地址不能为空
PAYMENT_MERCHANT_ID_EMPTY | 118 | 支付商户号不能为空
PAYMENT_MERCHANT_ID_NOT_EXISTS | 119 | 支付商户号不存在
PAYMENT_SIGN_EMPTY | 120 | 验签字段不能为空
PAYMENT_SIGN_INVALID | 121 | 验签不通过
ORDER_EXISTS | 124 | 订单号已存在
SIDE_ERROR | 127 | 交易类型错误

CONTRACT_ADDRESS_NOT_EXISTS | 8 | 合约不存在
ORDER_NO_EMPTY | 19 | 订单号不能为空
TOKEN_ADDRESS_ERROR | 10001 | token地址不存在或错误
TOKEN_BALANCE_UNDERFINANCED | 10002 | token余额不足
GASLIMINT_SHORT | 10003 | gasLimit缺少
BALANCE_UNDERFINANCED | 10004 | 余额不足
APPROVE_TOKEN_BALANCE_UNDERFINANCED | 10005 | 授权token余额不足
CONTRACT_DEPLOY_ERROR | 10006 | 合约创建失败
PRIVATEKEY_ERROR | 10007 | 私钥错误
ADDRESS_ERROR | 10008 | 地址错误
RPC_REQUEST_FAILED | 20001 | rpc请求失败
RPC_ERROR | 30001 | 远程调用失败
NOT_ENOUGH_TRANSACTION_PARAMETER | 40001 | 参数不足
NOT_VALID_DATA_TO_RAW_TX | 40002 | 交易数据无效
NOT_VALID_TYPE_TO_TRANSFER | 40003 | 交易类型无效
PARAMETER_INVALID | 40004 | 参数无效
SIGN_DID_INFO_INVALID | 40005 | did信息签名错误
TRANSFER_FAILED | 40006 | 交易失败
NO_INFO | 40007 | 未查询到信息