网站 虚拟目录,装修设计专业,怎么注册一个自己的网址,wordpress换语言环境 #xff1a; fisco bcos 3.11.0 webase-front : 3.1.1 console 3.8.0 table合约【3.2.0版本后的】 前言
最近在做毕设#xff0c;数据的存储方式考虑使用fisco-bcos的table表存储#xff0c;经过这几天的研究#xff0c;发现对于fisco2和 fisco3版本的table表合约功能… 环境 fisco bcos 3.11.0 webase-front : 3.1.1 console 3.8.0 table合约【3.2.0版本后的】 前言
最近在做毕设数据的存储方式考虑使用fisco-bcos的table表存储经过这几天的研究发现对于fisco2和 fisco3版本的table表合约功能差异还是比较大的比较起来V3的table合约功能性更丰富更加的方便开发。 读者们要是没用过v3的链子可以在fisco3 这里简单启动一条链子Air版本的搭建和fisco2搭建的链子命令无多大差别【文章后面也有对应的控制台搭建命令注意控制台2和3版本的链子不互通】 然后就是webase-front要使用3.0以上的版本链接在这里https://webasedoc.readthedocs.io/zh-cn/lab/docs/WeBASE-Install/developer.html 关于fisco3 的Table合约
不知道是不是webase-front 版本的问题我并未在其代码仓库里找到Table.sol合约的文件只有KVTable.sol合约。然后我去github的fisco仓库找到了fisco3的版本合约文件还附带两个合约都需要import进去才行 [更新一下这些合约也可以在控制台3.8.0上的contracts/solidity文件夹上找到注意v3版本有两个Table合约一个是3.2.0版本以上一个是3.2.0以前的版本我所有介绍的是3.2.0以上的官方文档给的是3.2.0以前的例子]
Table.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.10 0.8.20;
pragma experimental ABIEncoderV2;
import ./EntryWrapper.sol;// KeyOrder指定Key的排序规则字典序和数字序如果指定为数字序key只能为数字
enum KeyOrder {Lexicographic, Numerical}
struct TableInfo {KeyOrder keyOrder;string keyColumn;string[] valueColumns;
}// 更新字段用于update
struct UpdateField {string columnName;// 考虑工具类string value;
}// 筛选条件大于、大于等于、小于、小于等于
enum ConditionOP {GT, GE, LT, LE, EQ, NE, STARTS_WITH, ENDS_WITH, CONTAINS}
struct Condition {ConditionOP op;string field;string value;
}// 数量限制
struct Limit {uint32 offset;// count limit max is 500uint32 count;
}// 表管理合约是静态Precompiled有固定的合约地址
abstract contract TableManager {// 创建表传入TableInfofunction createTable(string memory path, TableInfo memory tableInfo) public virtual returns (int32);// 创建KV表传入key和value字段名function createKVTable(string memory tableName, string memory keyField, string memory valueField) public virtual returns (int32);// 只提供给Solidity合约调用时使用function openTable(string memory path) public view virtual returns (address);// 变更表字段// 只能新增字段不能删除字段新增的字段默认值为空不能与原有字段重复function appendColumns(string memory path, string[] memory newColumns) public virtual returns (int32);// 获取表信息function descWithKeyOrder(string memory tableName) public view virtual returns (TableInfo memory);
}// 表合约是动态PrecompiledTableManager创建时指定地址
abstract contract Table {// 按key查询entryfunction select(string memory key) public virtual view returns (Entry memory);// 按条件批量查询entrycondition为空则查询所有记录function select(Condition[] memory conditions, Limit memory limit) public virtual view returns (Entry[] memory);// 按照条件查询count数据function count(Condition[] memory conditions) public virtual view returns (uint32);// 插入数据function insert(Entry memory entry) public virtual returns (int32);// 按key更新entryfunction update(string memory key, UpdateField[] memory updateFields) public virtual returns (int32);// 按条件批量更新entrycondition为空则更新所有记录function update(Condition[] memory conditions, Limit memory limit, UpdateField[] memory updateFields) public virtual returns (int32);// 按key删除entryfunction remove(string memory key) public virtual returns (int32);// 按条件批量删除entrycondition为空则删除所有记录function remove(Condition[] memory conditions, Limit memory limit) public virtual returns (int32);
}abstract contract KVTable {function get(string memory key) public view virtual returns (bool, string memory);function set(string memory key, string memory value) public virtual returns (int32);
}EntryWrapper.sol
这个类似于mybatisplus里面的wrapper条件构造器用来进行附加查询条件使用还有Entry用来做返回数据的数据结构
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.10 0.8.20;
pragma experimental ABIEncoderV2;
import ./Cast.sol;// 记录用于select和insert
struct Entry {string key;string[] fields; // 考虑2.0的Entry接口临时Precompiled的问题考虑加工具类接口
}contract EntryWrapper { Cast constant cast Cast(address(0x100f)); Entry entry;constructor(Entry memory _entry) public {entry _entry;}function setEntry(Entry memory _entry) public {entry _entry;}function getEntry() public view returns(Entry memory) {return entry;}function fieldSize() public view returns (uint256) {return entry.fields.length;}function getInt(uint256 idx) public view returns (int256) {require(idx 0 idx fieldSize(), Index out of range!);return cast.stringToS256(entry.fields[idx]);}function getUInt(uint256 idx) public view returns (uint256) {require(idx 0 idx fieldSize(), Index out of range!);return cast.stringToU256(entry.fields[idx]);}function getAddress(uint256 idx) public view returns (address) {require(idx 0 idx fieldSize(), Index out of range!);return cast.stringToAddr(entry.fields[idx]);}function getBytes64(uint256 idx) public view returns (bytes1[64] memory) {require(idx 0 idx fieldSize(), Index out of range!);return bytesToBytes64(bytes(entry.fields[idx]));}function getBytes32(uint256 idx) public view returns (bytes32) {require(idx 0 idx fieldSize(), Index out of range!);return cast.stringToBytes32(entry.fields[idx]);}function getString(uint256 idx) public view returns (string memory) {require(idx 0 idx fieldSize(), Index out of range!);return entry.fields[idx];}function set(uint256 idx, int256 value) public returns(int32) {require(idx 0 idx fieldSize(), Index out of range!);entry.fields[idx] cast.s256ToString(value);return 0;}function set(uint256 idx, uint256 value) public returns(int32) {require(idx 0 idx fieldSize(), Index out of range!);entry.fields[idx] cast.u256ToString(value);return 0;}function set(uint256 idx, string memory value) public returns(int32) {require(idx 0 idx fieldSize(), Index out of range!);entry.fields[idx] value;return 0;}function set(uint256 idx, address value) public returns(int32) {require(idx 0 idx fieldSize(), Index out of range!);entry.fields[idx] cast.addrToString(value);return 0;}function set(uint256 idx, bytes32 value) public returns(int32) {require(idx 0 idx fieldSize(), Index out of range!);entry.fields[idx] cast.bytes32ToString(value);return 0;}function set(uint256 idx, bytes1[64] memory value) public returns(int32) {require(idx 0 idx fieldSize(), Index out of range!);entry.fields[idx] string(bytes64ToBytes(value));return 0;}function setKey(string memory value) public {entry.key value;}function getKey() public view returns (string memory) {return entry.key;}function bytes64ToBytes(bytes1[64] memory src) private pure returns(bytes memory) {bytes memory dst new bytes(64);for(uint32 i 0; i 64; i) {dst[i] src[i][0];}return dst;}function bytesToBytes64(bytes memory src) private pure returns(bytes1[64] memory) {bytes1[64] memory dst;for(uint32 i 0; i 64; i) {dst[i] src[i];}return dst;}
}Cast.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.10 0.8.20;
pragma experimental ABIEncoderV2;abstract contract Cast {function stringToS256(string memory) public virtual view returns (int256);function stringToS64(string memory) public virtual view returns (int64);function stringToU256(string memory) public virtual view returns (uint256);function stringToAddr(string memory) public virtual view returns (address);function stringToBytes32(string memory) public virtual view returns (bytes32);function s256ToString(int256) public virtual view returns (string memory);function s64ToString(int64) public virtual view returns (string memory);function u256ToString(uint256) public virtual view returns (string memory);function addrToString(address) public virtual view returns (string memory);function bytes32ToString(bytes32) public virtual view returns (string memory);
}编写TableTest
这里我直接用官网的例子代码进行测试不过官网例子与实际的table合约有出入需要进行修改 https://fisco-bcos-doc.readthedocs.io/zh-cn/latest/docs/contract_develop/c_contract/use_crud_precompiled.html // SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.10 0.8.20;
pragma experimental ABIEncoderV2;
import ./Table.sol;contract TestTable{// 创建TableManager对象其在区块链上的固定地址是0x1002
TableManager constant tm TableManager(address(0x1002));
Table table;
string constant TABLE_NAME t_test;
constructor () public{// 创建t_test表表的主键名为id其他字段名为name和agestring[] memory columnNames new string[](2);columnNames[0] name;columnNames[1] age;KeyOrder keyOrder;TableInfo memory tf TableInfo(KeyOrder.Numerical,id, columnNames);tm.createTable(TABLE_NAME, tf);// 获取真实的地址存在合约中address t_address tm.openTable(TABLE_NAME);require(t_address!address(0x0),);table Table(t_address);
} function insert(string memory id,string memory name,string memory age) public returns (int32){string[] memory columns new string[](2);columns[0] name;columns[1] age;Entry memory entry Entry(id, columns);int32 result table.insert(entry);// emit InsertResult(result);return result;
}function update(string memory id, string memory name, string memory age) public returns (int32){UpdateField[] memory updateFields new UpdateField[](2);updateFields[0] UpdateField(name, name);updateFields[1] UpdateField(age, age);int32 result table.update(id, updateFields);return result;
}function remove(string memory id) public returns(int32){int32 result table.remove(id);return result;
}function select(string memory id) public view returns (string memory,string memory)
{Entry memory entry table.select(id);string memory name;string memory age;if(entry.fields.length2){name entry.fields[0];age entry.fields[1];}return (name,age);
}// enum ConditionOP {GT, GE, LT, LE, EQ, NE, STARTS_WITH, ENDS_WITH, CONTAINS}
// struct Condition {
// ConditionOP op;
// string field;
// string value;
// }
function selectMore(string memory age)publicviewreturns (Entry[] memory entries)
{Condition[] memory conds new Condition[](1);Condition memory eq Condition({op: ConditionOP.EQ, field: age,value: age});conds[0] eq;Limit memory limit Limit({offset: 0, count: 100});entries table.select(conds, limit);return entries;
}}
TableInfo的问题
实际的TableInfo 结构如下
// KeyOrder指定Key的排序规则字典序和数字序如果指定为数字序key只能为数字
enum KeyOrder {Lexicographic, Numerical}
struct TableInfo {KeyOrder keyOrder;string keyColumn;string[] valueColumns;
}是需要三个参数的而官网的例子只用两个参数缺少的第一个参数是枚举类意思是你的主键是string类型还是数字类型需要标明。
Condition的问题
实际的Condition结构如下
// 筛选条件大于、大于等于、小于、小于等于
enum ConditionOP {GT, GE, LT, LE, EQ, NE, STARTS_WITH, ENDS_WITH, CONTAINS}
struct Condition {ConditionOP op;string field;string value;
}官网的只有两个参数缺少的那个参数是field也就是此条件是要用在表的哪个字段时安个。
关于主键的问题
在fisco2的table表合约开发时候因其的设计导致主键是可以重复的。 但在测试fisco3的table表合约开发的时候我用重复的主键添加多个数据发现它遵守了主键唯一的规则有兴趣的读者可以去测试一下特别是用TestTable的selectMore把field改成主键字段可以测试到返回不了多个数据
结语
这段时间会继续开发v3的table合约在开发的时候遇到的坑和新发现会持续更新到博客上 文章转载自: http://www.morning.ctlbf.cn.gov.cn.ctlbf.cn http://www.morning.bsqkt.cn.gov.cn.bsqkt.cn http://www.morning.yqwrj.cn.gov.cn.yqwrj.cn http://www.morning.pwdrc.cn.gov.cn.pwdrc.cn http://www.morning.mhnrx.cn.gov.cn.mhnrx.cn http://www.morning.kycwt.cn.gov.cn.kycwt.cn http://www.morning.mjats.com.gov.cn.mjats.com http://www.morning.qlck.cn.gov.cn.qlck.cn http://www.morning.nyhtf.cn.gov.cn.nyhtf.cn http://www.morning.zkrzb.cn.gov.cn.zkrzb.cn http://www.morning.lzqdl.cn.gov.cn.lzqdl.cn http://www.morning.glbnc.cn.gov.cn.glbnc.cn http://www.morning.rrcxs.cn.gov.cn.rrcxs.cn http://www.morning.nyplp.cn.gov.cn.nyplp.cn http://www.morning.fypgl.cn.gov.cn.fypgl.cn http://www.morning.mzmqg.cn.gov.cn.mzmqg.cn http://www.morning.kwxr.cn.gov.cn.kwxr.cn http://www.morning.rbqlw.cn.gov.cn.rbqlw.cn http://www.morning.ltywr.cn.gov.cn.ltywr.cn http://www.morning.tqrbl.cn.gov.cn.tqrbl.cn http://www.morning.rgpsq.cn.gov.cn.rgpsq.cn http://www.morning.nqbs.cn.gov.cn.nqbs.cn http://www.morning.mgbcf.cn.gov.cn.mgbcf.cn http://www.morning.fnjrh.cn.gov.cn.fnjrh.cn http://www.morning.wkgyz.cn.gov.cn.wkgyz.cn http://www.morning.ltffk.cn.gov.cn.ltffk.cn http://www.morning.qxbsq.cn.gov.cn.qxbsq.cn http://www.morning.txlxr.cn.gov.cn.txlxr.cn http://www.morning.rmjxp.cn.gov.cn.rmjxp.cn http://www.morning.drnjn.cn.gov.cn.drnjn.cn http://www.morning.tdqhs.cn.gov.cn.tdqhs.cn http://www.morning.hqwtm.cn.gov.cn.hqwtm.cn http://www.morning.jcypk.cn.gov.cn.jcypk.cn http://www.morning.syrzl.cn.gov.cn.syrzl.cn http://www.morning.cwjxg.cn.gov.cn.cwjxg.cn http://www.morning.wwdlg.cn.gov.cn.wwdlg.cn http://www.morning.srgnd.cn.gov.cn.srgnd.cn http://www.morning.dpzcc.cn.gov.cn.dpzcc.cn http://www.morning.lmpfk.cn.gov.cn.lmpfk.cn http://www.morning.qsy37.cn.gov.cn.qsy37.cn http://www.morning.knlgk.cn.gov.cn.knlgk.cn http://www.morning.clbsd.cn.gov.cn.clbsd.cn http://www.morning.gqtxz.cn.gov.cn.gqtxz.cn http://www.morning.rglp.cn.gov.cn.rglp.cn http://www.morning.cljpz.cn.gov.cn.cljpz.cn http://www.morning.ktblf.cn.gov.cn.ktblf.cn http://www.morning.mfmx.cn.gov.cn.mfmx.cn http://www.morning.jhtrb.cn.gov.cn.jhtrb.cn http://www.morning.yggwn.cn.gov.cn.yggwn.cn http://www.morning.zynjt.cn.gov.cn.zynjt.cn http://www.morning.msbpb.cn.gov.cn.msbpb.cn http://www.morning.huarma.com.gov.cn.huarma.com http://www.morning.bpmz.cn.gov.cn.bpmz.cn http://www.morning.fbhmn.cn.gov.cn.fbhmn.cn http://www.morning.kcypc.cn.gov.cn.kcypc.cn http://www.morning.cpkcq.cn.gov.cn.cpkcq.cn http://www.morning.xkhxl.cn.gov.cn.xkhxl.cn http://www.morning.wmmjw.cn.gov.cn.wmmjw.cn http://www.morning.rdzlh.cn.gov.cn.rdzlh.cn http://www.morning.nngq.cn.gov.cn.nngq.cn http://www.morning.rwdbz.cn.gov.cn.rwdbz.cn http://www.morning.ztrht.cn.gov.cn.ztrht.cn http://www.morning.ssqwr.cn.gov.cn.ssqwr.cn http://www.morning.wfqcs.cn.gov.cn.wfqcs.cn http://www.morning.rdmn.cn.gov.cn.rdmn.cn http://www.morning.tfrlj.cn.gov.cn.tfrlj.cn http://www.morning.cznsq.cn.gov.cn.cznsq.cn http://www.morning.lblsx.cn.gov.cn.lblsx.cn http://www.morning.ghjln.cn.gov.cn.ghjln.cn http://www.morning.fphbz.cn.gov.cn.fphbz.cn http://www.morning.dmhs.cn.gov.cn.dmhs.cn http://www.morning.bqxxq.cn.gov.cn.bqxxq.cn http://www.morning.smmby.cn.gov.cn.smmby.cn http://www.morning.yszrk.cn.gov.cn.yszrk.cn http://www.morning.rkfh.cn.gov.cn.rkfh.cn http://www.morning.mlycx.cn.gov.cn.mlycx.cn http://www.morning.hffjj.cn.gov.cn.hffjj.cn http://www.morning.mnbgx.cn.gov.cn.mnbgx.cn http://www.morning.qtqjx.cn.gov.cn.qtqjx.cn http://www.morning.tqbw.cn.gov.cn.tqbw.cn