以太坊中gas、gasPrice、gasLimit是什么?手续费不足异常(insufficient funds)的解决

1. 什么是gas?
gas是“燃料”的意思。在以太坊区块链上实现了一个EVM(以太坊虚拟机)的代码运行环境,在链上执行写入操作时,网络中的每个全节点都会进行相同的计算并存储相同的值。
这种执行的消耗是昂贵的,为了促使大家将能在链下进行的运算都不放到链上进行,也为了奖励矿工,在链上每执行一个写入操作时,都需要支付一定的费用,用gas为单位来计数。
每个在链上可以执行的命令都设置了一个消耗的gas值,例:PUSH操作需要消耗3个gas,一次转账一般要消耗21000 gas,gas使用ether来支付。
1 ether = 1 x 10^18 wei = 1 x 10^9 Gwei 。
注意:无论您执行的命令是成功还是失败,都需要支付计算费用,即使失败,节点也验证并执行了您的交易(计算),因此必须和成功执行支付一样的费用。

2. 什么是gasPrice?
Gas Price就是你愿意为一个单位的Gas出多少ether,一般用Gwei作单位。
Gas Price 越高,就表示交易中每运算一步,会支付更多的ether。
通过gas price可以节省矿工费用,但也会减慢矿工打包的速度。因为,矿工会优先打包gas price设置高的交易,如果您想加快转账,您可以把gas price设置得更高,这样您就可以插队靠前。
以太坊的交易手续费为:TxFee = gas * gas Price,单位Gwei。
一次转账一般要消耗21000 gas,如果你设置的gas Price = 1000000000wei = 1Gwei,则此次转账的交易手续费为:TxFee = 21000 Gwei = 0.000021 ether。
A账户欲向B账户转账4 ether,则要求A账户至少要有 4 + 0.000021 = 4. 000021 ethrer。
最后值得一提的是Gas Price 越高,你提交的交易会越快被矿工接纳。 但通常人们都不愿多支付手续费, 那么究竟应该将Gas Price设置为多少,才可以保证在能接受的时间内,让交易被确认到区域链上呢?
我们可以为交易定义gas price,具体的值可以参考 ETH gas station 。这里能看到以太坊区块链上最近完成的交易对应的消耗单价、记录时间、等待时间、手续费均价等。根据自身交易需求,我们可以参考右下Safelow/Standard/Fast三个速度对应的gasPrice。

3. 如何设置gas和gasPrice?
为了能让交易更快地被执行,我们可以在发起交易时设置gas和gasPrice,还可以设置noce,设置方法如下:
eth.sendTransaction({
    from: 0x4fd9555dd1309e7a2a356ea7e92c1b41cb7bb144,
    to: 0xf7deba629960e4f31f1aba61927f6f1e966c4462, 
    value: web3.toWei(1, "ether"), 
    gas: 60000,
    gasPrice: web3.toWei(40,'gwei'),
    nonce: 30
});      
1
2
3
4
5
6
7
8
参考链接:
以太坊转账 gas 费用太低,一直 pending 怎么办

4. 什么是gasLimit?
Gas Limit就是一次交易中gas的可用上限,也就是你的交易中最多会执行多少步运算。 由于交易复杂程度各有不同,
确切的Gas消耗量是在完成交易后才会知道,因此在你提交交易之前,需要为交易设定一个Gas用量的上限。
每个区块有gas limit,即单个区块允许的最多gas总量,可以用来决定单个区块中能打包多少笔交易。
我们每一次交易或合约调用都要设置一个gas limit,如果该次操作所使用的gas数量小于或等于您所设置的gas limit,则会被执行。但如果gas总消耗量超过gas limit,所有的操作都会被重置,但费用依旧会被收取——因为要奖励已经付出劳动的矿工。
在执行中实际消耗的gas值总和叫gas used,gas used未达到gas Limit, 那么只会按实际gas used 收取交易服务费,没有使用完的gas会退还到原账号。根据我查找的资料来看,这里所说的gas Limit就是指chapter 3中的gas属性。
如果您尝试将一个会使用超过当前区块gas limit的交易打包,则会被网络拒绝,会反馈below gas limit。
5. 手续费不足异常(insufficient funds)的解决
在多主机多节点的转账过程中,自己本来想从节点01的A账户(里面有4 ether)向节点02的B账户(里面0 ether)转账1 ether,粗心的将节点03搞成了节点01。节点03的A账户里面0 ether,因此报出了insufficient funds异常。
> eth.sendTransaction({from:eth.accounts[1],to:"0x4161514855682c94e3cbcb4808eb8766cf889e17",value:web3.toWei(1,"ether")})
Error: insufficient funds for gas * price + value
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at :1:1
1
2
3
4
5
6
因此查询了insufficient funds异常的解决办法,汇总如下:
① 创世区块的配置问题:关于以太坊私有链中进行交易时余额不足的问题处理,更改了chainId,估计很难遇到由chainId引起的异常。
② 更靠谱的方法是,计算一下gas*gasPrice + value 是不是大于当前账户的值,这里的value是指交易金额。参考链接:https://liankexing.com/question/question_page/id/757.html。

自己就是属于上面的第二种情况,而且是一种很极端的情况,对没有任何余额的账户进行转账操作!傻逼了~

如何计算gas*gasPrice + value 是不是大于当前账户的值?

//使用eth.estimateGas()方法来估计gas消耗量
> gas = eth.estimateGas({from:from, to: to, value: web3.toWei(2,"ether")})
21000
//获取gasPrice,单位为 wei
> eth.gasPrice
1000000000
//计算交易手续费TxFee
> fee = gas*eth.gasPrice
21000000000000
//计算gas*gasPrice + 2 ether
> parseInt(fee) + parseInt(web3.toWei(2,"ether"))
2000021000000000000
//查看账户余额
> eth.getBalance(eth.accounts[0])
201000042000000000000
//账户余额远大于gas*gasPrice + value,可以执行转账
> eth.sendTransaction({from:eth.accounts[1],to:"0x4161514855682c94e3cbcb4808eb8766cf889e17",value:web3.toWei(1,"ether")})
INFO [03-24|11:49:52.745] Setting new local account                address=0x74f3141E22E415dD9eDAae9CD1EF26E4EF704984
INFO [03-24|11:49:52.746] Submitted transaction                    fullhash=0x6c82be3da7181b7d2c44398f35453e2d21e16a2cb376b29556d1fb30c4addb51 recipient=0x4161514855682C94e3CBcb4808eb8766cf889e17
"0x6c82be3da7181b7d2c44398f35453e2d21e16a2cb376b29556d1fb30c4addb51"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
计算方法的参考链接:
以太坊估算交易gas消耗量
以太坊中以太币及代币计量单位
以太坊手续费不足异常(insufficient funds)

参考链接:
以太坊中的gas、gas price、gas limit到底是什么
以太坊中的Gas、GasPrice和GasLimit是什么?
以太坊中的交易及交易费用

你可能感兴趣的:(区块链)