Data-Export
Data-Export copied to clipboard
合约导出报错 decoder.decodeEvents failed
**链底层版本:**V3.6.0
**Solc版本:**0.8.11
**Data-Export版本:**V3
问题:
合约建表正常,但获取上链的字段数据时报错decoder.decodeEvents failed
合约文件为:
Uploading Test.sol…
合约代码贴出: // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.6.10 <0.8.20; pragma experimental ABIEncoderV2;
import "./Table.sol"; import "./Cast.sol";
contract Test { event CreateResult(int256 count); event InsertResult(int256 count); event UpdateResult(int256 count); event RemoveResult(int256 count);
Cast constant cast = Cast(address(0x100f));
TableManager constant tm = TableManager(address(0x1002));
Table table;
string constant TABLE_NAME = "t_testV3434";
constructor () public {
// create table
string[] memory columnNames = new string[](3);
columnNames[0] = "name";
columnNames[1] = "age";
columnNames[2] = "status";
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 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.length == 3){
name = entry.fields[0];
age = entry.fields[1];
}
return (name, age);
}
function insert(string memory id, string memory name, string memory age) public returns (int32){
Entry memory entry = Entry(id, new string[](3));
entry.fields[0] = name;
entry.fields[1] = age;
entry.fields[2] = "init";
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);
emit UpdateResult(result);
return result;
}
function remove(string memory id) public returns(int32){
int32 result = table.remove(id);
emit RemoveResult(result);
return result;
}
function select(int64 idLow, int64 idHigh) public view returns (string[] memory)
{
Limit memory limit = Limit(0, 500);
Condition[] memory cond = new Condition[](2);
cond[0] = Condition(ConditionOP.GT, "id", cast.s64ToString(idLow));
cond[1] = Condition(ConditionOP.LE, "id", cast.s64ToString(idHigh));
Entry[] memory entries = table.select(cond, limit);
string[] memory names = new string[](entries.length);
for(uint i = 0; i < names.length; i++)
{
names[i] = entries[i].fields[0];
}
return names;
}
function count(int64 idLow, int64 idHigh) public view returns (uint32)
{
Condition[] memory cond = new Condition[](2);
cond[0] = Condition(ConditionOP.GT, "id", cast.s64ToString(idLow));
cond[1] = Condition(ConditionOP.LE, "id", cast.s64ToString(idHigh));
return table.count(cond);
}
function update(int64 idLow, int64 idHigh) public returns (int32)
{
UpdateField[] memory updateFields = new UpdateField[](1);
updateFields[0] = UpdateField("status", "updated");
Limit memory limit = Limit(0, 500);
Condition[] memory cond = new Condition[](2);
cond[0] = Condition(ConditionOP.GT, "id", cast.s64ToString(idLow));
cond[1] = Condition(ConditionOP.LE, "id", cast.s64ToString(idHigh));
return table.update(cond, limit, updateFields);
}
function remove(int64 idLow, int64 idHigh) public returns (int32)
{
Limit memory limit = Limit(0, 500);
Condition[] memory cond = new Condition[](2);
cond[0] = Condition(ConditionOP.GT, "id", cast.s64ToString(idLow));
cond[1] = Condition(ConditionOP.LE, "id", cast.s64ToString(idHigh));
return table.remove(cond, limit);
}
function createTable(string memory tableName, uint8 keyOrder, string memory key,string[] memory fields) public returns(int256){
require(keyOrder == 0 || keyOrder == 1);
KeyOrder _keyOrder = KeyOrder.Lexicographic;
if (keyOrder == 1)
{
_keyOrder = KeyOrder.Numerical;
}
TableInfo memory tf = TableInfo(_keyOrder, key, fields);
int32 result = tm.createTable(tableName,tf);
emit CreateResult(result);
return result;
}
function desc() public view returns(string memory, string[] memory){
TableInfo memory ti = tm.descWithKeyOrder(TABLE_NAME);
return (ti.keyColumn,ti.valueColumns);
}
}
可以断点下么,看下具体原因
我linux环境跑的,你直接部署这个合约跑跑看下吧。import 里的都是官方的。
好的 目前数据导出还未适配3.6的链,我们这边跑一下,也欢迎PR
另外,需要提供下
上述依赖的合约
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 500 uint32 count; }
// 表管理合约,是静态Precompiled,有固定的合约地址 abstract contract TableManager { // 创建表,传入TableInfo function 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);
}
// 表合约,是动态Precompiled,TableManager创建时指定地址 abstract contract Table { // 按key查询entry function select(string memory key) public virtual view returns (Entry memory);
// 按条件批量查询entry,condition为空则查询所有记录
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更新entry
function update(string memory key, UpdateField[] memory updateFields) public virtual returns (int32);
// 按条件批量更新entry,condition为空则更新所有记录
function update(Condition[] memory conditions, Limit memory limit, UpdateField[] memory updateFields) public virtual returns (int32);
// 按key删除entry
function remove(string memory key) public virtual returns (int32);
// 按条件批量删除entry,condition为空则删除所有记录
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);
}
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);
}
第二个框框里的那个不需要提供
対,都是console下原生的,那个Test.sol,其实是原生的TableTest.sol
対,都是console下原生的,那个Test.sol,其实是原生的TableTest.sol
请问是做了什么插入操作么,给个插入的数据结构
本地测试insert数据导出是正常的
数据导出的表结构是正常的,但你的插入后 id name age 这三字段没数据啊
您好,有时间请帮忙确认下为什么表里导出的合约字段数据都是空的
我再看下 你上面的报错是插入了什么数据结构呢
有时间的话 可以直接用debug下项目在本地,方便复现问题,也可以提PR
你随便插个和字段类型符合看下就知道啦,比如 call ./test/v2 insert 34 34 45 你前面说正常那张截图,里面的有insert操作,但 id name age 这三字段都是空的,这就是有问题啊
大概定位到了 我这边看下
事务是有啊,我也有。你看看insert_method 那个表的id name age 这三字段有数据吗?
好的谢谢
我提交到新分支,你down下看看,建议多pr 共建
https://github.com/WeBankBlockchain/Data-Export/tree/v3_method_fix
OK Thx 麻烦你了
你好,上面的问题已解决。但多插几条数据调试时会出现报错 CrawlRunner run failed
清理掉数据库 重新启动 可能有脏数据
这个办法没用,会一直时不时报这个错,但不影响数据导出功能