Data-Export icon indicating copy to clipboard operation
Data-Export copied to clipboard

合约导出报错 decoder.decodeEvents failed

Open xp007123 opened this issue 10 months ago • 28 comments

**链底层版本:**V3.6.0 **Solc版本:**0.8.11 **Data-Export版本:**V3 问题: 合约建表正常,但获取上链的字段数据时报错decoder.decodeEvents failed 92fef8f29b04188257a74451bc9732f 46f3f14d4edab942e3d2e993d316251 合约文件为: Uploading Test.sol…

xp007123 avatar Apr 19 '24 07:04 xp007123

合约代码贴出: // 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);
}

}

xp007123 avatar Apr 19 '24 07:04 xp007123

可以断点下么,看下具体原因

wangyue168git avatar Apr 22 '24 08:04 wangyue168git

我linux环境跑的,你直接部署这个合约跑跑看下吧。import 里的都是官方的。

xp007123 avatar Apr 22 '24 08:04 xp007123

好的 目前数据导出还未适配3.6的链,我们这边跑一下,也欢迎PR

wangyue168git avatar Apr 22 '24 08:04 wangyue168git

另外,需要提供下 image 上述依赖的合约

wangyue168git avatar Apr 22 '24 08:04 wangyue168git

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

}

xp007123 avatar Apr 22 '24 08:04 xp007123

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

}

xp007123 avatar Apr 22 '24 08:04 xp007123

第二个框框里的那个不需要提供

xp007123 avatar Apr 22 '24 08:04 xp007123

image 部署报错 我看依赖的都是控制台下原生的 对吧

wangyue168git avatar Apr 22 '24 08:04 wangyue168git

対,都是console下原生的,那个Test.sol,其实是原生的TableTest.sol

xp007123 avatar Apr 22 '24 09:04 xp007123

対,都是console下原生的,那个Test.sol,其实是原生的TableTest.sol

请问是做了什么插入操作么,给个插入的数据结构

wangyue168git avatar Apr 24 '24 03:04 wangyue168git

本地测试insert数据导出是正常的 image

wangyue168git avatar Apr 24 '24 03:04 wangyue168git

数据导出的表结构是正常的,但你的插入后 id name age 这三字段没数据啊

xp007123 avatar Apr 24 '24 07:04 xp007123

您好,有时间请帮忙确认下为什么表里导出的合约字段数据都是空的

xp007123 avatar Apr 25 '24 07:04 xp007123

我再看下 你上面的报错是插入了什么数据结构呢

wangyue168git avatar Apr 26 '24 06:04 wangyue168git

有时间的话 可以直接用debug下项目在本地,方便复现问题,也可以提PR

wangyue168git avatar Apr 26 '24 06:04 wangyue168git

你随便插个和字段类型符合看下就知道啦,比如 call ./test/v2 insert 34 34 45 你前面说正常那张截图,里面的有insert操作,但 id name age 这三字段都是空的,这就是有问题啊

xp007123 avatar Apr 26 '24 06:04 xp007123

image

wangyue168git avatar Apr 26 '24 07:04 wangyue168git

大概定位到了 我这边看下

wangyue168git avatar Apr 26 '24 07:04 wangyue168git

事务是有啊,我也有。你看看insert_method 那个表的id name age 这三字段有数据吗?

xp007123 avatar Apr 26 '24 07:04 xp007123

好的谢谢

xp007123 avatar Apr 26 '24 07:04 xp007123

image

wangyue168git avatar Apr 26 '24 07:04 wangyue168git

我提交到新分支,你down下看看,建议多pr 共建

wangyue168git avatar Apr 26 '24 07:04 wangyue168git

https://github.com/WeBankBlockchain/Data-Export/tree/v3_method_fix

wangyue168git avatar Apr 26 '24 07:04 wangyue168git

OK Thx 麻烦你了

xp007123 avatar Apr 26 '24 07:04 xp007123

你好,上面的问题已解决。但多插几条数据调试时会出现报错 CrawlRunner run failed image

xp007123 avatar Apr 26 '24 08:04 xp007123

清理掉数据库 重新启动 可能有脏数据

wangyue168git avatar Apr 29 '24 03:04 wangyue168git

这个办法没用,会一直时不时报这个错,但不影响数据导出功能

xp007123 avatar Apr 29 '24 03:04 xp007123