使用webase测试链码,发交易是交易失败,为什么会报"PrecompiledError"?

发布于 2021-05-17 09:22:53

我的方法是这样写的,只要把其中

entry.set("account_address", _address);

这一句删除,就能正常工作;如果加上,编译能通过,但是发交易会报错

function accountRegister(string memory account, address _address, uint asset) public returns (int256)
    {
        int256 ret_code = 0;
        int256 ret = 0;
        
        uint256 a1 = 0;
        (ret,a1) = accountSelect(account);
        if(ret != 0){
            Table table = tableFactory.openTable(TABLE_NAME2);
            Entry entry = table.newEntry();
            
            entry.set("account",account);
            entry.set("account_address", _address);
            entry.set("asset_value", asset);
            //插入tableFactory.createTable(TABLE_NAME2,"account", "account_address,asset_value");
            int count = table.insert(account,entry);
            if (count == 1){
                ret_code = 0;//successful
            } else{
                // 失败:无权限或者其他错误
                ret_code = -2;
            }
            
        }else{
            // 业务已存在
            ret_code = -1;
        }
        
        
        emit RegisterAccountEvent(ret_code, account, asset,_address);
        
        return ret_code;
       
    }

全部的代码是这样的,几乎一样的deviceSelect方法能够正常使用

pragma solidity>=0.4.24 <0.6.11;
pragma experimental ABIEncoderV2;

import "./Table.sol";

contract rentTest {
    
    event RegisterEvent(int256 ret, string device_id, string device_type, address owner, uint expense);
    event RegisterAccountEvent(int256 ret, string account, uint256 asset_value,address account_address);

    TableFactory tableFactory;
    string constant TABLE_NAME = "device";//设备信息
    string constant TABLE_NAME2 = "asset";//资产信息
    constructor() public {
        tableFactory = TableFactory(0x1001); //The fixed address is 0x1001 for TableFactory
        // the parameters of createTable are tableName,keyField,"vlaueFiled1,vlaueFiled2,vlaueFiled3,..."
        tableFactory.createTable(TABLE_NAME, "device_id", "device_type,owner,expense");
        tableFactory.createTable(TABLE_NAME2,"account", "account_address,asset_value");
    }
    
    /*
    描述 : 根据设备 Id 查询业务上链数据 
    参数 : 
        device_id
    返回值:
        参数一: 成功返回 0, 数据不存在返回-1 
        参数二、三、四: 第一个参数为 0 时有效,上链的业务数据,分别是:拥有者账户地址、设备种类、每小时租金
    */
    function deviceSelect(string _id) public constant returns (int256,address,string,uint256){
        Table table = tableFactory.openTable(TABLE_NAME);
        Entries entries = table.select(_id,table.newCondition());
        
        if (0 == uint256(entries.size())) { 
            return (-1, 0,"",0); 
        } else {
            Entry entry = entries.get(0);
            return (0,entry.getAddress("owner"),entry.getString("device_type"),entry.getUInt("expense")); 

        }
    }
    
    /*
    描述 : 注册新设备,设备基本信息上链 
    参数 : 
        _id:设备id
        _type:设备种类
        _expense:每小时租金
    返回值:
         0:成功
        -1:设备已存在
        -2:无权限或者其他错误
    */
    function deviceRegister(string memory _id, string memory _type, uint _expense) public returns (int256)
    {
        int256 ret_code = 0;
        int256 ret = 0;
        
        address a1 = 0;
        string memory a2 = "";
        uint256 a3 = 0;
        (ret,a1,a2,a3) = deviceSelect(_id);
        if(ret != 0){
            Table table = tableFactory.openTable(TABLE_NAME);
            Entry entry = table.newEntry();
            
            entry.set("device_id",_id);
            entry.set("device_type", _type);
            entry.set("owner", msg.sender);
            entry.set("expense", _expense);
            //插入
            int count = table.insert(_id,entry);
            if (count == 1){
                ret_code = 0;//successful
            } else{
                // 失败:无权限或者其他错误
                ret_code = -2;
            }
            
        }else{
            // 业务已存在
            ret_code = -1;
        }
        
        
        emit RegisterEvent(ret_code, _id, _type, msg.sender, _expense);
        
        return ret_code;
       
    }
    
    
    
    /*
    描述 : 根据资产账户查询资产金额
    参数 :
            account : 资产账户

    返回值:
            参数一: 成功返回0, 账户不存在返回-1
            参数二: 第一个参数为0时有效,资产金额
    */
    function accountSelect(string account) public constant returns(int256,address,uint256) {
        // 打开表
        Table table = tableFactory.openTable(TABLE_NAME2);
        // 查询
        Entries entries = table.select(account, table.newCondition());
        uint256 asset_value = 0;
        if (0 == uint256(entries.size())) {
            return (-1, 0,asset_value);
        } else {
            Entry entry = entries.get(0);
            return (0, entry.getAddress("account_address"),uint256(entry.getInt("asset_value")));
        }
    }

    /*
    描述 : 资产注册
    参数 :
            account : 资产账户
            amount  : 资产金额
    返回值:
            0  资产注册成功
            -1 资产账户已存在
            -2 其他错误
    */
    // function accountRegister(string account, uint256 asset_value) public returns(int256){
    //     int256 ret_code = 0;
    //     int256 ret= 0;
    //     uint256 temp_asset_value = 0;
    //     // 查询账户是否存在
    //     (ret, temp_asset_value) = accountSelect(account);
    //     if(ret != 0) {
    //         Table table = tableFactory.openTable(TABLE_NAME2);

    //         Entry entry = table.newEntry();
    //         entry.set("account", account);
    //         entry.set("asset_value", int256(asset_value));
    //         entry.set("account_address", msg.sender);
    //         // 插入
    //         int count = table.insert(account, entry);
    //         if (count == 1) {
    //             // 成功
    //             ret_code = 0;
    //         } else {
    //             // 失败? 无权限或者其他错误
    //             ret_code = -2;
    //         }
    //     } else {
    //         // 账户已存在
    //         ret_code = -1;
    //     }

    //     emit RegisterAccountEvent(ret_code, account, asset_value,msg.sender);

    //     return ret_code;
    // }
    
    function accountRegister(string memory account, address _address, uint asset) public returns (int256)
    {
        int256 ret_code = 0;
        int256 ret = 0;
        address a1 = 0;
        uint256 a2 = 0;
        (ret,a1,a2) = accountSelect(account);
        if(ret != 0){
            Table table = tableFactory.openTable(TABLE_NAME2);
            Entry entry = table.newEntry();
            
            entry.set("account",account);
            entry.set("account_address", _address);
            entry.set("asset_value", asset);
            //插入tableFactory.createTable(TABLE_NAME2,"account", "account_address,asset_value");
            int count = table.insert(account,entry);
            if (count == 1){
                ret_code = 0;//successful
            } else{
                // 失败:无权限或者其他错误
                ret_code = -2;
            }
            
        }else{
            // 业务已存在
            ret_code = -1;
        }
        
        
        emit RegisterAccountEvent(ret_code, account, asset,_address);
        
        return ret_code;
       
    }
}

查看更多

关注者
0
被浏览
1.7k
1 个回答
林宣名
林宣名 2021-05-20
厦门哈希科技有限公司CTO&amp;联合创始人,区块链小学生, FISCO BCOS C# SDK作者 ,区块链实战教程作者,开源拥抱者。

你看一下你table 合约版本是否支持 address 类型参数set,最新的几个版本好像支持,旧的是不支持,不支持的话,需要将 address 类型进行类型转换@nthmnqy

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览