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值

输出

参数说明
truekey值查询成功,返回value值
falsekey值不存在

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
  2. syntax = "proto3";
  3. option optimize_for = LITE_RUNTIME;
  4. package anchor;
  5. message 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. // 定义表格的主键,表格的索引
  2. struct 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. // 声明表格
  10. xchain::cdt::Table<entity> _entity;

1.1.6.3. put

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

输入

参数说明
t待插入的数据项

输出

参数说明
true插入成功
false插入失败

样例

  1. // 参考样例 contractsdk/cpp/example/anchor.cc
  2. DEFINE_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

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

输入

参数说明
input查询关键字
t返回的数据项

输出

参数说明
true查询成功
false查询失败

样例

  1. DEFINE_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

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

输入

参数说明
input查询关键字

输出

参数说明
TableIterator符合条件的迭代器

样例

  1. DEFINE_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

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

输入

参数说明
t一个数据项

输出

参数说明
true删除成功
false删除失败

样例

  1. DEFINE_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, nilkey值查询成功,返回value值
_, 非nilkey值不存在

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结束关键字

输出

参数说明
IteratorInterator的接口

样例

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

1.3. Java接口API

1.3.1. getObject

键值获取

public byte[] getObject(byte[] key)

输入

参数说明
key查询的key值

输出

参数说明
valuekey值查询成功,返回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 newIterator(byte[] start, byte[] limit)

输入

参数说明
start初始关键字
limit结束关键字

输出

参数说明
IteratorInterator的接口

样例

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

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

输入

参数说明
module模块名
contract合约名
method合约方法
args合约参数

输出

参数说明
Response合约返回值

1.3.10. crossQuery

跨链查询

public Response crossQuery(String uri, Map args)

输入

参数说明
uri跨链路由地址
args合约参数

输出

参数说明
Response合约返回值