我正在构建一个关于以太坊的游戏作为我的第一个项目,我正面临存储和气体限制。我希望在部署之后在区块链上存储一个存储智能合约以进行查询。我真的需要初始化一个固定长度的数组,其中包含我手动插入的常量值。我的情况如下:
contract A {
...some states variables/modifiers and events......
uint[] public vector = new uint[](162);
vector = [.......1, 2, 3,......];
function A () {
....some code....
ContractB contract = new ContractB(vector);
}
....functions....
}
此代码未部署。显然我超过混音的气体限制。我尝试了以下方法:
我真的需要只有一个向量,因为它代表了一个图的边集,其中ContractB是构建图的数据结构。向量元素的排序如下:
vector = [edge1From, edge1To, edge2From, edge2To,.......]
我得到了81条边(向量中有162个条目)。
我认为我可以创建一个setData函数,在部署之后逐个调用此函数来推送向量中的值,但这不是我的情况,因为我需要在调用之前填充向量
ContractB contract = new ContractB(vector);
现在我可以看到我有两个疑问:
1)我是否错误地尝试在A构造函数内的函数调用中传递vector作为参数?
2)我可以看到我可以为边创建双重映射。像
这样的东西mapping (bool => mapping(uint => uint))
然后我需要多键值映射(从同一点开始的更多边缘)我会有问题像我对向量一样初始化所有映射?
答案 0 :(得分:0)
如果阵列的值范围足够小,则可以使用更适合uints
的尺寸来节省耗气量。以太坊将值存储到32字节的插槽中,并为每个使用的插槽支付20,000气体。如果您能够使用较小尺寸uint
(请记住,uint
与uint256
相同),您就可以节省燃气使用量。
例如,请考虑以下合同:
pragma solidity ^0.4.19;
contract Test {
uint256[100] big;
uint128[100] small;
function addBig(uint8 index, uint256 num) public {
big[index] = num;
}
function addSmall(uint8 index, uint128 num1, uint128 num2) public {
small[index] = num1;
small[index + 1] = num2;
}
}
每次使用先前未使用的索引调用addBig()
将导致执行成本略高于20,000气体,并导致将一个值添加到阵列中。每次调用addSmall()
将花费大约26,000,但是您要向阵列添加2个元素。两者都只使用1个存储槽。如果您可以小于uint128
,则可以获得更好的结果。
另一个选项(取决于您是否需要操纵数组数据)是存储您的vector
离线链。您可以使用oracle检索数据或将数据存储在IPFS中。
如果这些选项都不适用于您的用例,那么您必须更改数据结构和/或使用多个事务来初始化阵列。
答案 1 :(得分:0)
为什么合同需要在施工时初始化?
这应该有效
pragma solidity ^0.4.2;
contract Graph {
address owner;
struct GraphEdge {
uint128 from;
uint128 to;
}
GraphEdge[] public graph;
bool public initialized = false;
constructor() public {
owner = msg.sender;
}
function addEdge(uint128 edgeFrom, uint128 edgeTo) public {
require(!initialized);
graph.push(GraphEdge({
from: edgeFrom,
to: edgeTo
}));
}
function finalize() public {
require(msg.sender == owner);
initialized = true;
}
}
contract ContractB {
Graph graph;
constructor(address graphAddress) public {
Graph _graph = Graph(graphAddress);
require(_graph.initialized());
graph = _graph;
}
}