gas 不够导致函数调用没写入数据
问题描述:
开发了一个智能合约,其中有个函数由于写入的参数太长消耗GAS超过交易默认设定的GAS,交易被回滚(回滚时不会有任何提示信息)。
pragma solidity ^0.4.18;
contract orderData {
struct orderProduct {
address seller; // 卖家
address buyers; // 买家
uint256 id;
string productName;
uint256 unitPrice;
uint256 totalPrice;
uint256 purchaseQuantity; // 购买数量
string subTiem; // 订单提交时间
string payTime; // 支付时间
uint256 orderStatus;// 订单状态:1是没支付;2是已经支付;3 确认收货;4 是申请退款;5是退款完成
}
mapping(uint256 =>orderProduct ) orderProductMap;
function setOrderProductMap(address _seller,address _buyers,uint256 _id,string _productName,
uint256 _unitPrice,uint256 _totalPrice,uint256 _purchaseQuantity,string _subTiem,
uint256 _orderStatus) public {
orderProductMap[_id].seller=_seller;
orderProductMap[_id].buyers=_buyers;
orderProductMap[_id].id=_id;
orderProductMap[_id].productName=_productName;
orderProductMap[_id].unitPrice=_unitPrice;
orderProductMap[_id].totalPrice=_totalPrice;
orderProductMap[_id].purchaseQuantity=_purchaseQuantity;
orderProductMap[_id].subTiem=_subTiem;
//orderProductMap[_id].payTime=_payTime;
orderProductMap[_id].orderStatus=_orderStatus;
}
function getOrderProductMap(uint256 _id) public constant returns (address,address ,uint256 ,string ,
uint256 ,uint256 ,uint256 ,string ,string,
uint256
) {
/*return(orderProductMap[_id].seller,
orderProductMap[_id].buyers,
orderProductMap[_id].id,
orderProductMap[_id].productName,
orderProductMap[_id].unitPrice,
orderProductMap[_id].totalPrice,
//orderProductMap[_id].purchaseQuantity,
//orderProductMap[_id].subTiem,
//orderProductMap[_id].payTime,
orderProductMap[_id].orderStatus);*/ // 直接访问maping 元素只能访问7个元素,
//多了就报堆栈太深
orderProduct memory op = orderProduct(orderProductMap[_id].seller,
orderProductMap[_id].buyers,
orderProductMap[_id].id,
orderProductMap[_id].productName,
orderProductMap[_id].unitPrice,
orderProductMap[_id].totalPrice,
orderProductMap[_id].purchaseQuantity,
orderProductMap[_id].subTiem,
orderProductMap[_id].payTime,
orderProductMap[_id].orderStatus);
return(op.seller,op.buyers,op.id,op.productName,
op.unitPrice,op.totalPrice,op.purchaseQuantity,
op.subTiem,op.payTime,op.orderStatus
);
}
/*function getOrderProductMap(uint256 _id) public returns (address) {
return(orderProductMap[_id].seller);
}*/
function setPayTime(uint256 _id,string _payTime,uint256 _orderStatus) public {
orderProductMap[_id].payTime = _payTime;
orderProductMap[_id].orderStatus = _orderStatus;
}
}
在 Remix 编译合约,并复制 WEB3DEPLOY 的代码,粘贴到 geth 的终端上 部署智能合约
连接 geth
geth attach \\localhost\pipe\geth.ipc
部署智能合约
调用 setOrderProductMap 函数数据没写入区块链。
acCall = orderdataContract.at("0xb9b855a6b9b7ddcc04e15ec6977b3b087d30f95b") // 括号中是合约地址
acCall.setOrderProductMap("0x962402fce3af625e871e88a1a6019c4fc1443f87","0x6806004996a2d30c8f661a962495f51f1b79c2d6",2,"xiaomi5",2100,4200,2,"2018-06-28 17:33:10",1)
通过 acCall.getOrderProductMap(2) 查看数据为空。
通过 estimateGas 函数查看调用合约方法预估的GAS
acCall.setOrderProductMap.estimateGas("0x962402fce3af625e871e88a1a6019c4fc1443f87","0x6806004996a2d30c8f661a962495f51f1b79c2d6",2,"华为荣耀5测试测试测试测试测试测试测试测试测试测试测试测试",2100,4200,2,"2018-06-28 17:33:10",1)
估算出的GAS 为 12.382 万。
执行合约的方法 setOrderProductMap
通过执行 setOrderProductMap 的交易地址查看交易信息,可以看到调用setOrderProductMap函数时提供的gas 只有9万,比估算的 gas 要少。由于 gas 不足所以交易被回滚了。
eth.getTransaction("0xf422cd53fa30304e921aa9007db396b4bb3d59cad41b30bf99deb0eed603001d")
调用setOrderProductMap函数时设置GAS为100万,数据写入成功。
acCall.setOrderProductMap("0x962402fce3af625e871e88a1a6019c4fc1443f87","0x6806004996a2d30c8f661a962495f51f1b79c2d6",2,"xiaomi5",2100,4200,2,"2018-06-28 17:33:10",1,{gas:1000000})