1. 智能合约SDK使用说明

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

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()