Edit me

数字资产

Version 1.0.0

English / 中文

钱包文件及规范

钱包文件是一个Json格式的数据存储文件,可同时存储多个数字身份和多个数字资产账户。具体参考钱包文件规范

为了管理数字资产,您首先需要创建/打开一个钱包文件。

//如果不存在钱包文件,会自动创建钱包文件。
OntSdk ontSdk = OntSdk.getInstance();
ontSdk.openWalletFile("Demo.json");

注:目前仅支持文件形式钱包文件,也可以扩展支持数据库或其他存储方式。

资产账户数据结构说明

address 是base58编码的账户地址。 label 是账户的名称。 isDefault表明账户是否是默认的账户。默认值为false。 lock 表明账户是否是被用户锁住的。客户端不能消费掉被锁的账户中的资金。 algorithm 是秘钥算法名称。 parameters 是加密算法所需参数。 curve 是椭圆曲线的名称。 key 是NEP-2格式的私钥。该字段可以为null(对于只读地址或非标准地址)。 encAlg 私钥加密的算法名称,固定为aes-256-ctr。 salt 私钥解密参数。 extra 是客户端存储额外信息的字段。该字段可以为null。 signatureScheme 是签名方案,用于交易签名。 hash hash算法,用于派生秘钥。

public class Account {
    public String label = "";
    public String address = "";
    public boolean isDefault = false;
    public boolean lock = false;
    public String algorithm = "";
    public Map parameters = new HashMap() ;
    public String key = "";
    @JSONField(name = "enc-alg")
    public String encAlg = "aes-256-gcm";
    public String salt = "";
    public String hash = "sha256";
    public String signatureScheme = "SHA256withECDSA";
    public Object extra = null;
}

数字资产账户管理

以下举例说明如何管理钱包中的资产账户。

  • 创建数字资产账号
OntSdk ontSdk = OntSdk.getInstance();
Account acct = ontSdk.getWalletMgr().createAccount("password");
//创建的账号或身份只在内存中,如果要写入钱包文件,需调用写入接口
ontSdk.getWalletMgr().writeWallet();
  • 移除数字资产账号
ontSdk.getWalletMgr().getWallet().removeAccount(address);
//写入钱包
ontSdk.getWalletMgr().writeWallet();
  • 设置默认数字资产账号
ontSdk.getWalletMgr().getWallet().setDefaultAccount(index);
ontSdk.getWalletMgr().getWallet().setDefaultAccount("address");

Note: index表示设置第index个account为默认账户,address表示设置该address对应的account为默认账户

原生数字资产接口

原生数字资产包括ONT和ONG。封装了构造交易、交易签名、发送交易。

1. 转账

String sendTransfer(Account sendAcct, String recvAddr, long amount, Account payerAcct, long gaslimit, long gasprice)

功能说明: 从发送方转移一定数量的资产到接收方账户

参数说明:

参数 字段 类型 描述 说明
输入参数 sendAcct Account 发送方账户 必选
  recvAddr Account 接收方地址 必选
  amount long 转移的资产数量 必选
  payerAcct Account 支付交易费用的账户 必选
  gaslimit long 声明发行者和申请者ontid 必选
  gasprice long gas价格 必选
输出参数 交易hash String 交易hash  

2. 授权转移资产

String sendApprove(Account sendAcct, String recvAddr, long amount, Account payerAcct, long gaslimit, long gasprice)

功能说明: sendAddr账户允许recvAddr转移amount数量的资产

参数说明:

参数 字段 类型 描述 说明
输入参数 sendAcct Account 发送方账户 必选
  recvAddr Account 接收方地址 必选
  amount long 授权的资产数量 必选
  payerAcct Account 支付交易费用的账户 必选
  gaslimit long 声明发行者和申请者ontid 必选
  gasprice long gas价格 必选
输出参数 交易hash String 交易hash  

3. TransferFrom

String sendTransferFrom(Account sendAcct, String fromAddr, String toAddr, long amount, Account payerAcct, long gaslimit, long gasprice)

功能说明: sendAcct账户从fromAddr账户转移amount数量的资产到toAddr账户

参数说明:

参数 字段 类型 描述 说明
输入参数 sendAcct Account 发送方账户 必选
  fromAddr Account 资产转出方地址 必选
  toAddr Account 资产转入方地址 必选
  amount long 转移的资产数量 必选
  payerAcct Account 支付交易费用的账户 必选
  gaslimit long 声明发行者和申请者ontid 必选
  gasprice long gas价格 必选
输出参数 交易hash String 交易hash  

4. 查询余额

long queryBalanceOf(String address)

功能说明: 查询账户address资产余额

参数说明:

address: 账户地址

返回值:账户余额

  1. 查询Allowance
    long queryAllowance(String fromAddr,String toAddr)
    

    功能说明: 查询fromAddr授权toAddr转移的数量

参数说明:

fromAddr: 授权转出方的账户地址

toAddr: 允许转入方的账户地址

返回值:授权转移的数量

6. 查询资产名

String queryName()

功能说明: 查询资产名信息

参数说明:

返回值:资产名称

7. 查询资产Symbol

String querySymbol()

功能说明: 查询资产Symbol信息

参数说明:

返回值:Symbol信息

8. 查询资产的精确度

long queryDecimals()

功能说明: 查询资产的精确度

参数说明:

返回值:精确度

9. 查询资产的总供应量

long queryTotalSupply()

功能说明: 查询资产的总供应量

参数说明:

返回值:总供应量

资产转移示例代码:

//step1:获得ontSdk实例
OntSdk sdk = OntSdk.getInstance();
sdk.setRpc(url);
sdk.openWalletFile("OntAssetDemo.json");
//step2:获得ont实例
ont = sdk.nativevm().ont()
//step3:调用转账方法
com.github.ontio.account.Account account1 = new com.github.ontio.account.Account(privateKey,SignatureScheme.SHA256WITHECDSA);
ontSdk.nativevm().ont().sendTransfer(account1,"TA4pCAb4zUifHyxSx32dZRjTrnXtxEWKZr",10000,account1,ontSdk.DEFAULT_GAS_LIMIT,0);

nep-5智能合约数字资产例子

nep-5文档:

https://github.com/neo-project/proposals/blob/master/nep-5.mediawiki

数字资产模板:

https://github.com/neo-project/examples/tree/master/ICO_Template

方法名 输入参数 返回值 描述
sendInit boolean preExec String 如果是true表示预执行以便测试是否已经初始化,如果是false初始化合约参数
sendTransfer String sendAddr, String password, String recvAddr, int amount String 转移资产
sendBalanceOf String addr String 获得账户余额
sendTotalSupply   String 获得总供应量
sendName   String 获取名字
sendDecimals   String 查询精度
sendSymbol   String 查询Token缩写

nep-5智能合约模板:

using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;
using Neo.SmartContract.Framework.Services.System;
using System;
using System.ComponentModel;
using System.Numerics;

namespace Nep5Template
{
    public class Nep5Template : SmartContract
    {
        //Token Settings
        public static string Name() => "Nep5Template Token";
        public static string Symbol() => "TMP";
        public static readonly byte[] community = "AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX".ToScriptHash();
        public static byte Decimals() => 8;
        private const ulong factor = 100000000; //decided by Decimals()

        //ICO Settings
        private const ulong totalAmount = 1000000000 * factor;
        private const ulong communityCap = 1000000000 * factor;

        [DisplayName("transfer")]
        public static event Action<byte[], byte[], BigInteger> Transferred;

        public static Object Main(string operation, params object[] args)
        {
            if (Runtime.Trigger == TriggerType.Application)
            {
                if (operation == "init") return Init();
                if (operation == "totalSupply") return TotalSupply();
                if (operation == "name") return Name();
                if (operation == "symbol") return Symbol();
                if (operation == "transfer")
                {
                    if (args.Length != 3) return false;
                    byte[] from = (byte[])args[0];
                    byte[] to = (byte[])args[1];
                    BigInteger value = (BigInteger)args[2];
                    return Transfer(from, to, value);
                }
                if (operation == "balanceOf")
                {
                    if (args.Length != 1) return 0;
                    byte[] account = (byte[])args[0];
                    return BalanceOf(account);
                }
                if (operation == "decimals") return Decimals();
            }
            return false;
        }

        // 初始化参数
        public static bool Init()
        {
            byte[] total_supply = Storage.Get(Storage.CurrentContext, "totalSupply");
            if (total_supply.Length != 0) return false;

            Storage.Put(Storage.CurrentContext, community, communityCap);
            Transferred(null, community, communityCap);

            Storage.Put(Storage.CurrentContext, "totalSupply", totalAmount);
            return true;
        }

        // get the total token supply
        // 获取已发行token总量
        public static BigInteger TotalSupply()
        {
            Runtime.CheckSig(new byte[1]{ 1 },  new byte[]{2},new byte[]{ 3});
            return Storage.Get(Storage.CurrentContext, "totalSupply").AsBigInteger();
        }

        // function that is always called when someone wants to transfer tokens.
        // 流转token调用
        public static bool Transfer(byte[] from, byte[] to, BigInteger value)
        {
            if (value <= 0) return false;
            if (!Runtime.CheckWitness(from)) return false;
            if (from == to) return true;
            BigInteger from_value = Storage.Get(Storage.CurrentContext, from).AsBigInteger();
            if (from_value < value) return false;
            if (from_value == value)
                Storage.Delete(Storage.CurrentContext, from);
            else
                Storage.Put(Storage.CurrentContext, from, from_value - value);
            BigInteger to_value = Storage.Get(Storage.CurrentContext, to).AsBigInteger();
            Storage.Put(Storage.CurrentContext, to, to_value + value);
            Transferred(from, to, value);
            return true;
        }

        // get the account balance of another account with address
        // 根据地址获取token的余额
        public static BigInteger BalanceOf(byte[] address)
        {
            return Storage.Get(Storage.CurrentContext, address).AsBigInteger();
        }
    }
}

查看如何部署和调用智能合约,详见smartcontract