1. gas
以太坊在区块链上实现了一个运行环境,被称为以太坊虚拟机(EVM)。每个参与到网络的节点都会运行都会运行EVM作为区块验证协议的一部分。他们会验证区块中涵盖的每个交易并在EVM中运行交易所触发的代码。每个网络中的全节点都会进行相同的计算并储存相同的值。合约执行会在所有节点中被多次重复,这个事实得使得合约执行的消耗变得昂贵,所以这也促使大家将能在链下进行的运算都不放到区块链上进行。对于每个被执行的命令都会有一个特定的消耗,用单位gas计数。每个合约可以利用的命令都会有一个相应的gas值。gas使用ETH来支付。
2. gas和交易消耗的gas
每笔交易都被要求包括一个gas limit(有的时候被称为startGas
)和一个交易愿为单位gas支付的费用。矿工可以有选择的打包这些交易并收取这些费用。在现实中,今天所有的交易最终都是由矿工选择的,但是用户所选择支付的交易费用多少会影响到该交易被打包所需等待的时长。如果该交易由于计算,包括原始消息和一些触发的其他消息,需要使用的gas数量小于或等于所设置的gas limit,那么这个交易会被处理。如果gas总消耗超过gas limit,那么所有的操作都会被复原,但交易是成立的并且交易费任会被矿工收取。区块链会显示这笔交易完成尝试,但因为没有提供足够的gas导致所有的合约命令都被复原。所以交易里没有被使用的超量gas都会以以太币的形式打回给交易发起者。因为gas消耗一般只是一个大致估算,所以许多用户会超额支付gas来保证他们的交易会被接受。这没什么问题,因为多余的gas会被退回给你。
Gas是由两个部分组成: Gas limit
(限制)* Gas Price
(价格)
一个交易的交易费由两个因素组成:
gasUsed
:该交易消耗的总gas数量gasPrice
:该交易中单位gas的价格(用以太币计算)交易费 = gasUsed * gasPrice
gasUsed
每个EVM中的命令都被设置了相应的gas消耗值。gasUsed是所有被执行的命令的gas消耗值总和。
区块gas limit
区块gas limit是单个区块允许的最多gas总量,以此可以用来决定单个区块中能打包多少笔交易。例如,我们有5笔交易的gas limit分别是10、20、30、40和50.如果区块gas limit是100,那么前4笔交易就能被成功打包进入这个区块。矿工有权决定将哪些交易打包入区块。所以,另一个矿工可以选择打包最后两笔交易进入这个区块(50+40),然后再将第一笔交易打包(10)。如果你尝试将一个会使用超过当前区块gas limit的交易打包,这个交易会被网络拒绝,你的以太坊客户端会反馈错误"交易超过区块gas limit"。以下例子是来自于以太坊StackExhcange的帖子。
目前区块的gas limit是 4,712,357 gas,数据来自于ethstats.net,这表示着大约224笔转账交易(gas limit为21000)可以被塞进一个区块(区块时间大约在15-20秒间波动)。这个协议允许每个区块的矿工调整区块gas limit,任意加减 1/2024(0.0976%)。
区块的gas limit是由在网络上的矿工决定的。与可调整的区块gas limit协议不同的是一个默认的挖矿策略,即大多数客户端默认最小区块gas limit为4,712,388。
以太坊上的矿工需要用一个挖矿软件,例如ethminer。它会连接到一个geth或者Parity以太坊客户端。Geth和Pairty都有让矿工可以更改配置的选项。这里是geth挖矿命令行选项以及Parity的选项。
一个重要需要注意的事情是内部交易或者消息不包含gasLimit。因为gas limit是由原始交易的外部创建者决定的(也就是外部拥有账户)。外部拥有账户设置的gas limit必须要高到足够将交易完成,包括由于此交易而产生的任何”子执行”,例如合约到合约的消息。如果,在一个交易或者信息链中,其中一个消息执行使gas已不足,那么这个消息的执行会被还原,包括任何被此执行触发的子消息。不过,父执行没必要被还原。
作者:孔德健
链接:https://www.jianshu.com/p/8fd649d41263
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
例如:
{
difficulty: 157870,
extraData: "0xd98301080d846765746888676f312e31302e338664617277696e",
gasLimit: 2635108496,
gasUsed: 21000,
hash: "0x015ddd6a3ae2a7415319cba0eea293b442ff2b5d22e9d0aadbf62929a5b7d127",
……
}
2
web3 源码发送一笔签名交易,签名内容为账户地址,得到一个130个64位字符码结果;
const Web3=require("web3")
//let web3=new Web3(new Web3.providers.HttpProvider("http://0.0.0.0:8545"))
let web3=new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:8545"))
web3.eth.getAccounts().then(function(accounts){
web3.eth.personal.unlockAccount(accounts[0],'liujp').then(function(err){
console.log(err)
web3.eth.sign(accounts[0],accounts[2])
.then(function(result){
web3.eth.estimateGas({from:accounts[0],to:accounts[1],data:result})
.then(function(value){
console.log(value)
})
console.log(result)
web3.eth.sendTransaction({from:accounts[0],to:accounts[1],value:web3.utils.toWei("2"),data:result}).then(function(val){
console.log(val)
})
})
})
})
//sign data
发送签名数据计算后打包的交易块儿如下:
{
difficulty: 140617,
extraData: "0xd98301080d846765746888676f312e31302e338664617277696e",
gasLimit: 2460911184,
gasUsed: 25356,
hash: "0x1faffb83f0f08d3aaa01604d339e8c7ce0e41ba895c0b81a3905397eb9594864",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x04a78a0ef3d868fdb9d7532c8b1ef7f49167f5a4",
mixHash: "0x89aa2ffbb803769d5bf52072cf9fdf7f81686b6ece72b78316ae866dc958f03a",
nonce: "0x2d6ac2944283758a",
number: 570,
parentHash: "0x1e540e531f6c959b25f60165483a54c67ec6e730b9c8ad3b446ffaf395f6dac6",
receiptsRoot: "0xd846e2a6d17355d13fbfa33c90d181fd72ec8e6631aca44dfbdcc173e2b51f8c",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 720,
stateRoot: "0x610d465c8aed0fbb8d026b15517f097e638d6a25d35d6de07f025139e6dd5891",
timestamp: 1533731373,
totalDifficulty: 84923387,
transactions: ["0xb7c9929adc769db25ebdd75b8e81d489fd679f5a9fce7152ae6fb3304b0ff4df"],
transactionsRoot: "0x863eb81e2b1e9c6c4f039938a01b26c61c9b0138636b5df3a2a10e2c9511ab39",
uncles: []
}
input如下,每两个为一位,可知64位非零和1位0值
0x3b 84 a8 04 7e ae 29 34 fc a2 dc b3 cf 61 19 11 ae 87 63 0f 19 4e 1a 8c cc 9b 20 c0 ba e5 0c 57 00 42 20 cf 26 e9 28 da e5 50 58 bd 2c fc 2e 3b 54 fe f7 a7 35 31 73 08 68 72 39 48 e9 3c f9 91 1c
总交易gas:
25356 = 交易费 + data处理费
input: 65字节:其中非零字节 64个,
=》 25356 = 21000(一笔交易)+ 64(位,data加密数据长度)*68+4
例3 输入一笔全0交易数据
估计:25356,使用21260;
21260=21000 + 4*65
{blockHash: '0x9b08fe576261f95423cdfbb000c30148b1774a63664398226727fac34f0fcaa7',
blockNumber: 708,
contractAddress: null,
cumulativeGasUsed: 21260,
from: '0x04a78a0ef3d868fdb9d7532c8b1ef7f49167f5a4',
gasUsed: 21260,
logs: [],
……
}
例4 输入一笔全1交易数据(数据长度130)
data: "0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
估计:25356,使用25420;
21260=21000 + 68*65(位)
{ blockHash: '0x60dcd93e9dc191b402b63e967dd1dddd3aa2a354fcf7610b46e6f1001e5cb9d2',
blockNumber: 2990,
contractAddress: null,
cumulativeGasUsed: 25420,
from: '0x04a78a0ef3d868fdb9d7532c8b1ef7f49167f5a4',
gasUsed: 25420,
logs: [],
……
}
测试data:
0x1a fe 5c ac1 bc b7 ec de 4c 3a 22 c3 69 7f 13 d0 eb a8 d7 1b fd 5d 4e 7b b7 3f a1 0a 48 a7 3a 81 87 61 27 21 4a b4 c2 d2 a1 e0 e6 76 30 08 13 99 b8 20 6f 2e 1a 0c f7 60 d8 96 c0 6a 76 6d 0f b1 b
0xb0 3b 0e c3 35 24 58 bc 09 ac 9f a8 da d4 e9 18 79 80 e6 bb 64 3f 4e 58 fa 38 53 7b 02 cb b9 7b 4b 0a 70 51 59 f4 7e 07 05 e7 e2 1c 4d 42 a4 87 80 ea 2d 76 b6 c3 9a cb 07 98 00 44 18 65 60 ea 1c
0x3b84a 8047e ae293 4fca2 dcb3c f6119 11ae8 7630f 194e1 a8ccc 9b20c 0bae5 0c570 04220 cf26e 928da e5505 8bd2c fc2e3 b54fe f7a73 53173 08687 23948 e93cf 9911c
0x1000 00010 0000 00100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 0100 0000 01
0x3b 84 a8 04 7e ae 29 34 fc a2 dc b3 cf 61 19 11 ae 87 63 0f 19 4e 1a 8c cc 9b 20 c0 ba e5 0c 57 00 42 20 cf 26 e9 28 da e5 50 58 bd 2c fc 2e 3b 54 fe f7 a7 35 31 73 08 68 72 39 48 e9 3c f9 91 1c