Fisco Bcos学习 - Solidity合约开发

文章目录

    • 一、Solidity合约开发概述
    • 二、使用KVTable合约读写接口
      • 2.1 KVTable合约简介
      • 2.2 KVTable合约接口声明
      • 2.3 KVTable合约案例:KVTableTest.sol
      • 2.4 案例解析
    • 三、使用Table合约CRUD接口
      • 3.1 Table合约简介
      • 3.2 Table合约接口声明
      • 3.3 Table合约案例:TableTest.sol
      • 3.4 案例解析
    • 四、合约开发注意事项

一、Solidity合约开发概述

Solidity是一种面向对象的编程语言,专门为实现智能合约而设计,广泛应用于以太坊和FISCO BCOS等区块链平台。在FISCO BCOS中,Solidity合约与预编译(Precompiled)合约是两种主要的合约形式。其中,Solidity合约使用Solidity语法实现,最高支持0.5.2版本,具有灵活的开发模式,适合实现各种业务逻辑;而预编译合约使用C++开发,内置于平台,性能更优,适合逻辑固定但需要共识的场景。

本文将重点介绍FISCO BCOS中Solidity合约的开发,包括KVTable合约读写接口和Table合约CRUD接口的使用,帮助开发者快速掌握Solidity合约在区块链平台上的应用。

二、使用KVTable合约读写接口

2.1 KVTable合约简介

KVTable合约实现了键值型数据的读写方式,适合用于Key-Value存储场景。其核心接口包括:

  • KVTableFactory:用于创建和打开KVTable
  • Entry:表示一条记录,提供get和set方法
  • KVTable:每个键对应一条entry,提供get和set方法

2.2 KVTable合约接口声明

pragma solidity ^0.4.24;

contract KVTableFactory {
    function openTable(string) public view returns (KVTable);
    function createTable(string, string, string) public returns (int256);
}

contract Entry {
    function getInt(string) public constant returns (int256);
    function getUInt(string) public constant returns (int256);
    function getAddress(string) public constant returns (address);
    function getBytes64(string) public constant returns (bytes1[64]);
    function getBytes32(string) public constant returns (bytes32);
    function getString(string) public constant returns (string);
    function set(string, int256) public;
    function set(string, uint256) public;
    function set(string, string) public;
    function set(string, address) public;
}

contract KVTable {
    function get(string) public view returns (bool, Entry);
    function set(string, Entry) public returns (int256);
    function newEntry() public view returns (Entry);
}

2.3 KVTable合约案例:KVTableTest.sol

下面是一个完整的KVTable合约案例,实现了创建用户表t_kvtest并对其进行读写操作:

pragma solidity ^0.4.24;
import "./Table.sol";

contract KVTableTest {
    event SetResult(int256 count);
    KVTableFactory tableFactory;
    string constant TABLE_NAME = "t_kvtest";

    constructor() public {
        tableFactory = KVTableFactory(0x1010);
        tableFactory.createTable(TABLE_NAME, "id", "item_price,item_name");
    }

    function get(string id) public view returns (bool, int256, string) {
        KVTable table = tableFactory.openTable(TABLE_NAME);
        bool ok = false;
        Entry entry;
        (ok, entry) = table.get(id);
        int256 item_price;
        string memory item_name;
        if (ok) {
            item_price = entry.getInt("item_price");
            item_name = entry.getString("item_name");
        }
        return (ok, item_price, item_name);
    }

    function set(string id, int256 item_price, string item_name)
        public
        returns (int256)
    {
        KVTable table = tableFactory.openTable(TABLE_NAME);
        Entry entry = table.newEntry();
        entry.set("id", id);
        entry.set("item_price", item_price);
        entry.set("item_name", item_name);
        int256 count = table.set(id, entry);
        emit SetResult(count);
        return count;
    }
}

2.4 案例解析

  • 构造函数:初始化KVTableFactory并创建表t_kvtest,指定主键为"id",字段为"item_price"和"item_name"
  • get函数:根据id查询记录,返回查询结果、物品价格和物品名称
  • set函数:插入或更新记录,返回操作结果

三、使用Table合约CRUD接口

3.1 Table合约简介

Table合约提供了类似关系型数据库的CRUD(增删改查)接口,适合用于需要批量操作数据的场景。其核心接口包括:

  • TableFactory:用于打开和创建表
  • Condition:用于定义查询条件
  • Entry:表示单条数据记录
  • Entries:表示数据记录集
  • Table:提供select、insert、update、remove等方法

3.2 Table合约接口声明

pragma solidity ^0.4.24;

contract TableFactory {
    function openTable(string) public constant returns (Table);
    function createTable(string,string,string) public returns(int);
}

contract Condition {
    function EQ(string, int) public;
    function EQ(string, string) public;
    function NE(string, int) public;
    function NE(string, string) public;
    function GT(string, int) public;
    function GE(string, int) public;
    function LT(string, int) public;
    function LE(string, int) public;
    function limit(int) public;
    function limit(int, int) public;
}

contract Entry {
    function getInt(string) public constant returns(int);
    function getAddress(string) public constant returns(address);
    function getBytes64(string) public constant returns(byte[64]);
    function getBytes32(string) public constant returns(bytes32);
    function getString(string) public constant returns(string);
    function set(string, int) public;
    function set(string, string) public;
    function set(string, address) public;
}

contract Entries {
    function get(int) public constant returns(Entry);
    function size() public constant returns(int);
}

contract Table {
    function select(string, Condition) public constant returns(Entries);
    function insert(string, Entry) public returns(int);
    function update(string, Entry, Condition) public returns(int);
    function remove(string, Condition) public returns(int);
    function newEntry() public constant returns(Entry);
    function newCondition() public constant returns(Condition);
}

3.3 Table合约案例:TableTest.sol

下面是一个完整的Table合约案例,实现了创建用户表t_test并对其进行增删改查操作:

pragma solidity ^0.4.24;
import "./Table.sol";

contract TableTest {
    event CreateResult(int count);
    event InsertResult(int count);
    event UpdateResult(int count);
    event RemoveResult(int count);

    function create() public returns(int){
        TableFactory tf = TableFactory(0x1001);
        int count = tf.createTable("t_test", "name", "item_id,item_name");
        emit CreateResult(count);
        return count;
    }

    function select(string name) public constant returns(bytes32[], int[], bytes32[]){
        TableFactory tf = TableFactory(0x1001);
        Table table = tf.openTable("t_test");
        Condition condition = table.newCondition();
        Entries entries = table.select(name, condition);
        bytes32[] memory user_name_bytes_list = new bytes32[](uint256(entries.size()));
        int[] memory item_id_list = new int[](uint256(entries.size()));
        bytes32[] memory item_name_bytes_list = new bytes32[](uint256(entries.size()));
        for(int i=0; i

3.4 案例解析

  • create函数:创建表t_test,指定主键为"name",字段为"item_id"和"item_name"
  • select函数:根据name查询记录,返回查询结果集
  • insert函数:插入一条记录
  • update函数:更新符合条件的记录
  • remove函数:删除符合条件的记录

四、合约开发注意事项

  1. 表名唯一性:为实现AMDB创建的表可被多个合约共享访问,其表名是群组内全局可见且唯一的,无法在同一条链上的同一个群组中创建多个表名相同的表。

  2. 字段长度限制

    • Table合约的insert、remove、update和select函数中key的类型为string,长度最大支持255字符。
    • Entry的get/set接口的key的类型为string,长度最大支持255字符,value支持的类型有int256(int)、address和string,其中string不能超过16MB。
  3. 客户端调用:客户端需要调用转换为Java文件的合约代码,需要将Solidity合约和Table.sol放入控制台的contracts/solidity目录下,通过控制台的编译脚本sol2java.sh生成对应的Java文件。

  4. 存储引擎选择

    • 使用Table合约的CRUD接口时,推荐使用关系型数据库MySQL作为后端数据库,因为其支持批量操作和范围查询。
    • 使用KVTable合约的get/set接口时,推荐使用RocksDB作为后端数据库,因为RocksDB是Key-Value存储的非关系型数据库,单key操作效率更高。

更多详细内容请访问:https://www.bookstack.cn/read/fisco-bcos-2.4-zh/d29922a72208071e.md

你可能感兴趣的:(#,Fisco,Bcos,学习,区块链,Fisco,Bcos)