1. 智能合约SDK使用说明

XuperChain为方便用户开发属于自己的智能合约,提供了一整套SDK套件,即XuperCDT(XuperChain Crontract Development Toolkit),包含C++语言、Go语言和Java语言

1.1. C++接口API

1.1.1. get_object

bool ContextImpl::get_object(const std::string& key, std::string* value)

输入

参数

说明

key

查询的key值

value

根据key查到的value值

输出

参数

说明

true

key值查询成功,返回value值

false

key值不存在

1.1.2. put_object

bool ContextImpl::put_object(const std::string& key, const std::string& value)

输入

参数

说明

key

存入的key值

value

存入key值对应的value值

输出

参数

说明

true

存入db成功

false

存入db失败

1.1.3. delete_object

bool ContextImpl::delete_object(const std::string& key)

输入

参数

说明

key

将要删除的key值

输出

参数

说明

true

删除成功

false

删除失败

1.1.4. query_tx

bool ContextImpl::query_tx(const std::string &txid, Transaction* tx)

输入

参数

说明

txid

待查询的txid

tx

得到此txid的transaction

输出

参数

说明

true

查询交易成功

false

查询交易失败

1.1.5. query_block

bool ContextImpl::query_block(const std::string &blockid, Block* block)

输入

参数

说明

blockid

待查询的blockid

block

得到此blockid的block

输出

参数

说明

true

查询block成功

false

查询block失败

1.1.6. table

1.1.6.1. 定义表格

 1// 表格定义以proto形式建立,存放目录为contractsdk/cpp/pb
 2syntax = "proto3";
 3option optimize_for = LITE_RUNTIME;
 4package anchor;
 5message Entity {
 6    int64 id = 1;
 7    string name = 2;
 8    bytes desc = 3;
 9}
10// table名称为Entity,属性分别为id,name,desc

1.1.6.2. 初始化表格

 1// 定义表格的主键,表格的索引
 2struct entity: public anchor::Entity {
 3    DEFINE_ROWKEY(name);
 4    DEFINE_INDEX_BEGIN(2)
 5    DEFINE_INDEX_ADD(0, id, name)
 6    DEFINE_INDEX_ADD(1, name, desc)
 7    DEFINE_INDEX_END();
 8};
 9// 声明表格
10xchain::cdt::Table<entity> _entity;

1.1.6.3. put

1template <typename T>
2bool Table<T>::put(T t)

输入

参数

说明

t

待插入的数据项

输出

参数

说明

true

插入成功

false

插入失败

样例

 1// 参考样例 contractsdk/cpp/example/anchor.cc
 2DEFINE_METHOD(Anchor, set) {
 3    xchain::Context* ctx = self.context();
 4    const std::string& id= ctx->arg("id");
 5    const std::string& name = ctx->arg("name");
 6    const std::string& desc = ctx->arg("desc");
 7    Anchor::entity ent;
 8    ent.set_id(std::stoll(id));
 9    ent.set_name(name.c_str());
10    ent.set_desc(desc);
11    self.get_entity().put(ent);
12    ctx->ok("done");
13}

1.1.6.4. find

1template <typename T>
2bool Table<T>::find(std::initializer_list<PairType> input, T* t)

输入

参数

说明

input

查询关键字

t

返回的数据项

输出

参数

说明

true

查询成功

false

查询失败

样例

 1DEFINE_METHOD(Anchor, get) {
 2    xchain::Context* ctx = self.context();
 3    const std::string& name = ctx->arg("key");
 4    Anchor::entity ent;
 5    if (self.get_entity().find({{"name", name}}, &ent)) {
 6        ctx->ok(ent.to_str());
 7        return;
 8    }
 9    ctx->error("can not find " + name);
10}

1.1.6.5. scan

1template <typename T>
2std::unique_ptr<TableIterator<T>> Table<T>::scan(std::initializer_list<PairType> input)

输入

参数

说明

input

查询关键字

输出

参数

说明

TableIterator

符合条件的迭代器

样例

 1DEFINE_METHOD(Anchor, scan) {
 2    xchain::Context* ctx = self.context();
 3    const std::string& name = ctx->arg("name");
 4    const std::string& id = ctx->arg("id");
 5    // const std::string& desc = ctx->arg("desc");
 6    auto it = self.get_entity().scan({{"id", id},{"name", name}});
 7    Anchor::entity ent;
 8    int i = 0;
 9    std::map<std::string, bool> kv;
10    while(it->next()) {
11        if (it->get(&ent)) {
12            /*
13            std::cout << "id: " << ent.id()<< std::endl;
14            std::cout << "name: " << ent.name()<< std::endl;
15            std::cout << "desc: " << ent.desc()<< std::endl;
16            */
17            if (kv.find(ent.name()) != kv.end()) {
18                ctx->error("find duplicated key");
19                return;
20            }
21            kv[ent.name()] = true;
22            i += 1;
23        } else {
24            std::cout << "get error" << std::endl;
25        }
26    }
27    std::cout << i << std::endl;
28    if (it->error()) {
29        std::cout << it->error(true) << std::endl;
30    }
31    ctx->ok(std::to_string(i));
32}

1.1.6.6. del

1template <typename T>
2bool Table<T>::del(T t)

输入

参数

说明

t

一个数据项

输出

参数

说明

true

删除成功

false

删除失败

样例

 1DEFINE_METHOD(Anchor, del) {
 2    xchain::Context* ctx = self.context();
 3    const std::string& id= ctx->arg("id");
 4    const std::string& name = ctx->arg("name");
 5    const std::string& desc = ctx->arg("desc");
 6    Anchor::entity ent;
 7    ent.set_id(std::stoll(id));
 8    ent.set_name(name.c_str());
 9    ent.set_desc(desc);
10    self.get_entity().del(ent);
11    ctx->ok("done");
12}

1.2. Go接口API

1.2.1. GetObject

func GetObject(key []byte) ([]byte, error)

输入

参数

说明

key

查询的key值

输出

参数

说明

value, nil

key值查询成功,返回value值

_, 非nil

key值不存在

1.2.2. PutObject

func PutObject(key []byte, value []byte) error

输入

参数

说明

key

存入的key值

value

存入key值对应的value值

输出

参数

说明

nil

存入db成功

非nil

存入db失败

1.2.3. DeleteObject

func DeleteObject(key []byte) error

输入

参数

说明

key

将要删除的key值

输出

参数

说明

nil

删除成功

非nil

删除失败

1.2.4. QueryTx

func QueryTx(txid string) (*pb.Transaction, error)

输入

参数

说明

txid

待查询的txid

输出

参数

说明

tx, nil

查询交易成功, 得到此txid的transaction

_, 非nil

查询交易失败

1.2.5. QueryBlock

func QueryBlock(blockid string) (*pb.Block, error)

输入

参数

说明

blockid

待查询的blockid

输出

参数

说明

block, nil

查询block成功, 得到此blockid的block

_, 非nil

查询block失败

1.2.6. NewIterator

func NewIterator(start, limit []byte) Iterator

输入

参数

说明

start

初始关键字

limit

结束关键字

输出

参数

说明

Iterator

Interator的接口

样例

1Key() []byte
2Value() []byte
3Next() bool
4Error() error
5// Iterator 必须在使用完毕后关闭
6Close()

1.3. Java接口API

1.3.1. getObject

键值获取

public byte[] getObject(byte[] key)

输入

参数

说明

key

查询的key值

输出

参数

说明

value

key值查询成功,返回value值;为null时,查询失败

1.3.2. putObject

键值存储

public void putObject(byte[] key, byte[] value)

输入

参数

说明

key

存入的key值

value

存入key值对应的value值

输出

参数

说明

void

操作失败时,可捕捉异常;否则,成功

1.3.3. deleteObject

键值删除

public void deleteObject(byte[] key)

输入

参数

说明

key

将要删除的key值

输出

参数

说明

void

操作失败时,可捕捉异常;否则,成功

1.3.4. queryTx

交易查询

public Contract.Transaction queryTx(String txid)

输入

参数

说明

txid

待查询的txid

输出

参数

说明

tx

查询交易成功, 得到此txid的transaction;查询失败,抛出异常

1.3.5. queryBlock

区块查询

public Contract.Block queryBlock(String blockid)

输入

参数

说明

blockid

待查询的blockid

输出

1.3.6. newIterator

迭代器

public Iterator<ContractIteratorItem> newIterator(byte[] start, byte[] limit)

输入

参数

说明

start

初始关键字

limit

结束关键字

输出

参数

说明

Iterator

Interator的接口

样例

 1@ContractMethod
 2public Response getList(Context ctx) {
 3    byte[] start = ctx.args().get("start");
 4    if (start == null) {
 5        return Response.error("missing start");
 6    }
 7
 8    byte[] limit = PrefixRange.generateLimit(start);
 9    Iterator<ContractIteratorItem> iter = ctx.newIterator(start, limit);
10    int i = 0;
11    while (iter.hasNext()) {
12        ContractIteratorItem item = iter.next();
13        String key = bytesToString(item.getKey());
14        String value = bytesToString(item.getValue());
15        ctx.log("item: " + i + ", key: " + key + ", value: " + value);
16        i++;
17    }
18
19    return Response.ok("ok".getBytes());
20}

1.3.7. transfer

从合约向其他地址转账

public void transfer(String to, BigInteger amount)

输入

参数

说明

to

收款地址

amount

数量

输出

1.3.8. transferAmount

调用合约方法向合约转账时,获取转账的数量

public BigInteger transferAmount()

输入

输出

参数

说明

BigInteger

数量

1.3.9. call

跨合约调用

public Response call(String module, String contract, String method, Map<String, byte[]> args)

输入

参数

说明

module

模块名

contract

合约名

method

合约方法

args

合约参数

输出

参数

说明

Response

合约返回值

1.3.10. crossQuery

跨链查询

public Response crossQuery(String uri, Map<String, byte[]> args)

输入

参数

说明

uri

跨链路由地址

args

合约参数

输出

参数

说明

Response

合约返回值