Ethereum的gas成本问题
很多运行在Ethereum平台上的去中心化应用需要存储/获取数据,和传统应用程序访问PostgreSQL、MongoDB、Redis等等一样。EVM(Ethereum Virtual Machine)也确实允许我们将变量和状态存储到持久化的存储中去。我们看看下面这个简单的智能合约:
pragma solidity ^0.4.17;
contract Database {
bytes x;
function write(bytes _x) public {
x = _x;
}
function read() public view returns (bytes) {
return x;
}
}
我将这个智能合约部署到Rinkeby测试网络中,通过https://www.random.org产生了1024个字节的随机数,然后通过上面的write函数存储这1k的数据。这个交易的结果可以通过下面这个链接看到: https://rinkeby.etherscan.io/tx/0x6575badcafbc4db521e82904fa14b04bd8e862de1c82f62e064e699d0f90ebe3
这将消耗754,365个gas,按照20Gwei的gas价格,成本为0.0150873以太币,在Oct 17, 2017的时候,以太币的价格是328.79 USD/ETH。因此,在Ethereum主网络上,存储1KB数据的成本是$4.96。也就是说,存储1GB的数据,成本大约为5 Million USD。
其他存储思路
存储小量数据到EVM是可行的,但是如果要存储大块的数据,存储成本对大多数项目来说估计就太高了。一个途径是调整我们的数据存储策略,把数据进行链外存储(和前面我们提到的把数据存储在链上,是相反的)。链外存储有很多选择,IPFS和Swarmare是比较流行的两个,下面使用IPFS来示例,Swarm也是类似的。
了解IPFS
可以从这个链接wikipedia article了解IPFS :
InterPlanetary File System (IPFS)是一种用于创建永久性和去中心化文件的存储和共享协议。IPFS允许p2p存储,我们可以把它看成一个分布式的文件系统来存储数据。
低成本存储策略
将数据存储到IPFS后,IPFS将提供一个唯一的hash值。和把数据存储在合约上不同,我们仅仅需要把这个hash值存储到合约上,然后可以通过这个唯一的hash值来访问数据。
在生产环境中我们需要自己创建自己的IPFS节点,但INFURA 提供了一个开发人员可以免费使用的节点。可以从 https://npm.runkit.com/ 下载这段js代码来存储数据到IPFS :
const IPFS = require(‘ipfs-mini’);
const ipfs = new IPFS({host: ‘ipfs.infura.io’, port: 5001, protocol: ‘https’});
const randomData = “8803cf48b8805198dbf85b2e0d514320”; random bytes for testing
ipfs.add(randomData, (err, hash) => {
if (err) {
return console.log(err);
}
console.log(“HASH:”, hash);
});
上面的代码将返回一个hash值“Qmaj3ZhZtHynXc1tpnTnSBNsq8tZihMuV34wAvpURPZZMs” ,我们可以使用这个hash值来获取数据:
const IPFS = require(‘ipfs-mini’);
const ipfs = new IPFS({host: ‘ipfs.infura.io’, port: 5001, protocol: ‘https’});
const hash = “Qmaj3ZhZtHynXc1tpnTnSBNsq8tZihMuV34wAvpURPZZMs”;
ipfs.cat(hash, (err, data) => {
if (err) {
return console.log(err);
}
console.log(“DATA:”, data);
});
上面的代码会返回我们的数据: “8803cf48b8805198dbf85b2e0d514320”。值得注意的一点是,hash值的长度和数据的长度是没关系的,这也意味着我们可以在不增加Ethereum交易成本的情况下,存储大量(目前我还没发现数据长度的限制)的数据或文件到IPFS上。
我使用上面的智能合约存储之前产生的hash值到IPFS上 :
https://rinkeby.etherscan.io/tx/0x53ae68a0f7302d8808d836c560f54f83b2b870f02b136338c8abde03f2e3cfb9
消耗的gas下降到40,907,按20Gwei的单价计算,成本是0.00081814以太币,大约0.27 USD。我们可以看到,这个存储成本基本是可以接受的,同时无论我们存储什么样的数据到IPFS中,成本是相对稳定的。
演示工程: Stone Dapp
我构建了一个用于验证这个想法demo项目:Stone Dapp,大家可以自由下载 :
Github : https://github.com/didil/stone-dapp
Live version (Rinkeby) : https://stone-dapp.firebaseapp.com
另外:在上面的例子中,我把Gas的价格设置为20 GWei。为了让你可以选择不同的Gas价格,你可以访问:http://ethgasstation.info。ETH的Gas站提供交易确认时间评估和其它有用的状态信息展示。




