Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
b383ff0b
Commit
b383ff0b
authored
Mar 02, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New gas prices model
parent
73c52d16
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
193 additions
and
120 deletions
+193
-120
chain_manager.go
core/chain_manager.go
+6
-4
state_transition.go
core/state_transition.go
+9
-3
address.go
vm/address.go
+9
-9
common.go
vm/common.go
+44
-20
vm.go
vm/vm.go
+125
-84
No files found.
core/chain_manager.go
View file @
b383ff0b
...
...
@@ -28,11 +28,13 @@ type StateQuery interface {
func
CalcDifficulty
(
block
,
parent
*
types
.
Block
)
*
big
.
Int
{
diff
:=
new
(
big
.
Int
)
adjust
:=
new
(
big
.
Int
)
.
Rsh
(
parent
.
Difficulty
(),
10
)
if
block
.
Time
()
>=
parent
.
Time
()
+
8
{
diff
.
Sub
(
parent
.
Difficulty
(),
adjust
)
}
else
{
//
adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
//
if block.Time() >= parent.Time()+8 {
adjust
:=
new
(
big
.
Int
)
.
Div
(
parent
.
Difficulty
(),
big
.
NewInt
(
2048
)
)
if
(
block
.
Time
()
-
parent
.
Time
())
<
8
{
diff
.
Add
(
parent
.
Difficulty
(),
adjust
)
}
else
{
diff
.
Sub
(
parent
.
Difficulty
(),
adjust
)
}
return
diff
...
...
core/state_transition.go
View file @
b383ff0b
...
...
@@ -12,6 +12,12 @@ import (
const
tryJit
=
false
var
(
GasTx
=
big
.
NewInt
(
21000
)
GasTxNonZeroByte
=
big
.
NewInt
(
37
)
GasTxZeroByte
=
big
.
NewInt
(
2
)
)
/*
* The State transitioning model
*
...
...
@@ -170,7 +176,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
//sender.Nonce += 1
// Transaction gas
if
err
=
self
.
UseGas
(
vm
.
GasTx
);
err
!=
nil
{
if
err
=
self
.
UseGas
(
GasTx
);
err
!=
nil
{
return
}
...
...
@@ -178,9 +184,9 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
var
dgas
int64
for
_
,
byt
:=
range
self
.
data
{
if
byt
!=
0
{
dgas
+=
vm
.
GasData
.
Int64
()
dgas
+=
GasTxNonZeroByte
.
Int64
()
}
else
{
dgas
+=
1
// This is 1/5. If GasData changes this fails
dgas
+=
GasTxZeroByte
.
Int64
()
}
}
if
err
=
self
.
UseGas
(
big
.
NewInt
(
dgas
));
err
!=
nil
{
...
...
vm/address.go
View file @
b383ff0b
...
...
@@ -32,23 +32,23 @@ func PrecompiledContracts() map[string]*PrecompiledAccount {
// SHA256
string
(
ethutil
.
LeftPadBytes
([]
byte
{
2
},
20
))
:
&
PrecompiledAccount
{
func
(
l
int
)
*
big
.
Int
{
n
:=
big
.
NewInt
(
int64
(
l
+
31
)
/
32
+
1
)
n
.
Mul
(
n
,
GasSha256
)
return
n
n
:=
big
.
NewInt
(
int64
(
l
+
31
)
/
32
)
n
.
Mul
(
n
,
GasSha256
Word
)
return
n
.
Add
(
n
,
GasSha256Base
)
},
sha256Func
},
// RIPEMD160
string
(
ethutil
.
LeftPadBytes
([]
byte
{
3
},
20
))
:
&
PrecompiledAccount
{
func
(
l
int
)
*
big
.
Int
{
n
:=
big
.
NewInt
(
int64
(
l
+
31
)
/
32
+
1
)
n
.
Mul
(
n
,
GasRipemd
)
return
n
n
:=
big
.
NewInt
(
int64
(
l
+
31
)
/
32
)
n
.
Mul
(
n
,
GasRipemd
Word
)
return
n
.
Add
(
n
,
GasRipemdBase
)
},
ripemd160Func
},
string
(
ethutil
.
LeftPadBytes
([]
byte
{
4
},
20
))
:
&
PrecompiledAccount
{
func
(
l
int
)
*
big
.
Int
{
n
:=
big
.
NewInt
(
int64
(
l
+
31
)
/
32
+
1
)
n
.
Mul
(
n
,
Gas
MemCpy
)
n
:=
big
.
NewInt
(
int64
(
l
+
31
)
/
32
)
n
.
Mul
(
n
,
Gas
IdentityWord
)
return
n
return
n
.
Add
(
n
,
GasIdentityBase
)
},
memCpy
},
}
}
...
...
vm/common.go
View file @
b383ff0b
...
...
@@ -31,26 +31,48 @@ func NewVm(env Environment) VirtualMachine {
}
var
(
GasStep
=
big
.
NewInt
(
1
)
GasSha
=
big
.
NewInt
(
10
)
GasSLoad
=
big
.
NewInt
(
20
)
GasSStore
=
big
.
NewInt
(
100
)
GasSStoreRefund
=
big
.
NewInt
(
100
)
GasBalance
=
big
.
NewInt
(
20
)
GasCreate
=
big
.
NewInt
(
100
)
GasCall
=
big
.
NewInt
(
20
)
GasCreateByte
=
big
.
NewInt
(
5
)
GasSha3Byte
=
big
.
NewInt
(
10
)
GasSha256Byte
=
big
.
NewInt
(
50
)
GasRipemdByte
=
big
.
NewInt
(
50
)
GasMemory
=
big
.
NewInt
(
1
)
GasData
=
big
.
NewInt
(
5
)
GasTx
=
big
.
NewInt
(
500
)
GasLog
=
big
.
NewInt
(
32
)
GasSha256
=
big
.
NewInt
(
50
)
GasRipemd
=
big
.
NewInt
(
50
)
GasEcrecover
=
big
.
NewInt
(
500
)
GasMemCpy
=
big
.
NewInt
(
1
)
GasQuickStep
=
big
.
NewInt
(
2
)
GasFastestStep
=
big
.
NewInt
(
3
)
GasFastStep
=
big
.
NewInt
(
5
)
GasMidStep
=
big
.
NewInt
(
8
)
GasSlowStep
=
big
.
NewInt
(
10
)
GasExtStep
=
big
.
NewInt
(
20
)
GasStorageGet
=
big
.
NewInt
(
50
)
GasStorageAdd
=
big
.
NewInt
(
20000
)
GasStorageMod
=
big
.
NewInt
(
5000
)
GasLogBase
=
big
.
NewInt
(
2000
)
GasLogTopic
=
big
.
NewInt
(
2000
)
GasLogData
=
big
.
NewInt
(
8
)
GasCreate
=
big
.
NewInt
(
32000
)
GasCreateByte
=
big
.
NewInt
(
300
)
GasCall
=
big
.
NewInt
(
40
)
GasCallValueTransfer
=
big
.
NewInt
(
6700
)
GasCallNewAccount
=
big
.
NewInt
(
25000
)
GasReturn
=
big
.
NewInt
(
0
)
GasStop
=
big
.
NewInt
(
0
)
GasJumpDest
=
big
.
NewInt
(
1
)
RefundStorage
=
big
.
NewInt
(
15000
)
RefundSuicide
=
big
.
NewInt
(
24000
)
GasMemWord
=
big
.
NewInt
(
3
)
GasQuadCoeffWord
=
big
.
NewInt
(
1
)
GasContractByte
=
big
.
NewInt
(
200
)
GasTransaction
=
big
.
NewInt
(
21000
)
GasTxDataNonzeroByte
=
big
.
NewInt
(
37
)
GasTxZeroByte
=
big
.
NewInt
(
2
)
GasSha3Base
=
big
.
NewInt
(
30
)
GasSha3Word
=
big
.
NewInt
(
6
)
GasSha256Base
=
big
.
NewInt
(
60
)
GasSha256Word
=
big
.
NewInt
(
12
)
GasRipemdBase
=
big
.
NewInt
(
600
)
GasRipemdWord
=
big
.
NewInt
(
12
)
GasEcrecover
=
big
.
NewInt
(
3000
)
GasIdentityBase
=
big
.
NewInt
(
15
)
GasIdentityWord
=
big
.
NewInt
(
3
)
GasCopyWord
=
big
.
NewInt
(
3
)
Pow256
=
ethutil
.
BigPow
(
2
,
256
)
...
...
@@ -59,6 +81,8 @@ var (
U256
=
ethutil
.
U256
S256
=
ethutil
.
S256
Zero
=
ethutil
.
Big0
)
const
MaxCallDepth
=
1025
...
...
vm/vm.go
View file @
b383ff0b
...
...
@@ -769,27 +769,97 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
}
}
func
(
self
*
Vm
)
calculateGasAndSize
(
context
*
Context
,
caller
ContextRef
,
op
OpCode
,
statedb
*
state
.
StateDB
,
mem
*
Memory
,
stack
*
Stack
)
(
*
big
.
Int
,
*
big
.
Int
)
{
gas
:=
new
(
big
.
Int
)
addStepGasUsage
:=
func
(
amount
*
big
.
Int
)
{
if
amount
.
Cmp
(
ethutil
.
Big0
)
>=
0
{
gas
.
Add
(
gas
,
amount
)
}
type
req
struct
{
stack
int
gas
*
big
.
Int
}
var
_baseCheck
=
map
[
OpCode
]
req
{
// Req Stack Gas price
ADD
:
{
2
,
GasFastestStep
},
LT
:
{
2
,
GasFastestStep
},
GT
:
{
2
,
GasFastestStep
},
SLT
:
{
2
,
GasFastestStep
},
SGT
:
{
2
,
GasFastestStep
},
EQ
:
{
2
,
GasFastestStep
},
ISZERO
:
{
1
,
GasFastestStep
},
SUB
:
{
2
,
GasFastestStep
},
AND
:
{
2
,
GasFastestStep
},
OR
:
{
2
,
GasFastestStep
},
XOR
:
{
2
,
GasFastestStep
},
NOT
:
{
1
,
GasFastestStep
},
BYTE
:
{
2
,
GasFastestStep
},
CALLDATALOAD
:
{
1
,
GasFastestStep
},
CALLDATACOPY
:
{
3
,
GasFastestStep
},
MLOAD
:
{
1
,
GasFastestStep
},
MSTORE
:
{
2
,
GasFastestStep
},
MSTORE8
:
{
2
,
GasFastestStep
},
CODECOPY
:
{
3
,
GasFastestStep
},
MUL
:
{
2
,
GasFastStep
},
DIV
:
{
2
,
GasFastStep
},
SDIV
:
{
2
,
GasFastStep
},
MOD
:
{
2
,
GasFastStep
},
SMOD
:
{
2
,
GasFastStep
},
SIGNEXTEND
:
{
2
,
GasFastStep
},
ADDMOD
:
{
3
,
GasMidStep
},
MULMOD
:
{
3
,
GasMidStep
},
JUMP
:
{
1
,
GasMidStep
},
JUMPI
:
{
2
,
GasSlowStep
},
EXP
:
{
2
,
GasSlowStep
},
ADDRESS
:
{
0
,
GasQuickStep
},
ORIGIN
:
{
0
,
GasQuickStep
},
CALLER
:
{
0
,
GasQuickStep
},
CALLVALUE
:
{
0
,
GasQuickStep
},
CODESIZE
:
{
0
,
GasQuickStep
},
GASPRICE
:
{
0
,
GasQuickStep
},
COINBASE
:
{
0
,
GasQuickStep
},
TIMESTAMP
:
{
0
,
GasQuickStep
},
NUMBER
:
{
0
,
GasQuickStep
},
DIFFICULTY
:
{
0
,
GasQuickStep
},
GASLIMIT
:
{
0
,
GasQuickStep
},
POP
:
{
0
,
GasQuickStep
},
PC
:
{
0
,
GasQuickStep
},
MSIZE
:
{
0
,
GasQuickStep
},
GAS
:
{
0
,
GasQuickStep
},
BLOCKHASH
:
{
1
,
GasExtStep
},
BALANCE
:
{
0
,
GasExtStep
},
EXTCODESIZE
:
{
1
,
GasExtStep
},
EXTCODECOPY
:
{
4
,
GasExtStep
},
SLOAD
:
{
1
,
GasStorageGet
},
SSTORE
:
{
2
,
Zero
},
SHA3
:
{
1
,
GasSha3Base
},
CREATE
:
{
3
,
GasCreate
},
CALL
:
{
7
,
GasCall
},
CALLCODE
:
{
7
,
GasCall
},
JUMPDEST
:
{
0
,
GasJumpDest
},
SUICIDE
:
{
1
,
Zero
},
RETURN
:
{
2
,
Zero
},
}
func
baseCheck
(
op
OpCode
,
stack
*
Stack
,
gas
*
big
.
Int
)
{
if
r
,
ok
:=
_baseCheck
[
op
];
ok
{
stack
.
require
(
r
.
stack
)
gas
.
Add
(
gas
,
r
.
gas
)
}
}
addStepGasUsage
(
GasStep
)
func
toWordSize
(
size
*
big
.
Int
)
*
big
.
Int
{
tmp
:=
new
(
big
.
Int
)
tmp
.
Add
(
tmp
,
u256
(
31
))
tmp
.
Div
(
tmp
,
u256
(
32
))
return
tmp
}
func
(
self
*
Vm
)
calculateGasAndSize
(
context
*
Context
,
caller
ContextRef
,
op
OpCode
,
statedb
*
state
.
StateDB
,
mem
*
Memory
,
stack
*
Stack
)
(
*
big
.
Int
,
*
big
.
Int
)
{
var
(
gas
=
new
(
big
.
Int
)
newMemSize
*
big
.
Int
=
new
(
big
.
Int
)
)
baseCheck
(
op
,
stack
,
gas
)
var
newMemSize
*
big
.
Int
=
ethutil
.
Big0
var
additionalGas
*
big
.
Int
=
new
(
big
.
Int
)
// Stack Check, memory resize & gas phase
switch
op
{
// Stack checks only
case
ISZERO
,
CALLDATALOAD
,
POP
,
JUMP
,
NOT
,
EXTCODESIZE
,
BLOCKHASH
:
// 1
stack
.
require
(
1
)
case
JUMPI
,
ADD
,
SUB
,
DIV
,
MUL
,
SDIV
,
MOD
,
SMOD
,
LT
,
GT
,
SLT
,
SGT
,
EQ
,
AND
,
OR
,
XOR
,
BYTE
,
SIGNEXTEND
:
// 2
stack
.
require
(
2
)
case
ADDMOD
,
MULMOD
:
// 3
stack
.
require
(
3
)
case
SWAP1
,
SWAP2
,
SWAP3
,
SWAP4
,
SWAP5
,
SWAP6
,
SWAP7
,
SWAP8
,
SWAP9
,
SWAP10
,
SWAP11
,
SWAP12
,
SWAP13
,
SWAP14
,
SWAP15
,
SWAP16
:
n
:=
int
(
op
-
SWAP1
+
2
)
stack
.
require
(
n
)
...
...
@@ -800,112 +870,83 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
n
:=
int
(
op
-
LOG0
)
stack
.
require
(
n
+
2
)
gas
.
Set
(
GasLog
)
addStepGasUsage
(
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
int64
(
n
)),
GasLog
))
mSize
,
mStart
:=
stack
.
Peekn
()
addStepGasUsage
(
mSize
)
gas
.
Add
(
gas
,
GasLogBase
)
gas
.
Add
(
gas
,
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
int64
(
n
)),
GasLogTopic
))
gas
.
Add
(
gas
,
new
(
big
.
Int
)
.
Mul
(
mSize
,
GasLogData
))
newMemSize
=
calcMemSize
(
mStart
,
mSize
)
case
EXP
:
stack
.
require
(
2
)
gas
.
Set
(
big
.
NewInt
(
int64
(
len
(
stack
.
data
[
stack
.
Len
()
-
2
]
.
Bytes
())
+
1
)))
// Gas only
case
STOP
:
gas
.
Set
(
ethutil
.
Big0
)
case
SUICIDE
:
stack
.
require
(
1
)
gas
.
Set
(
ethutil
.
Big0
)
case
SLOAD
:
stack
.
require
(
1
)
gas
.
Set
(
GasSLoad
)
// Memory resize & Gas
gas
.
Add
(
gas
,
big
.
NewInt
(
int64
(
len
(
stack
.
data
[
stack
.
Len
()
-
2
]
.
Bytes
())
+
1
)))
case
SSTORE
:
stack
.
require
(
2
)
var
mult
*
big
.
Int
var
g
*
big
.
Int
y
,
x
:=
stack
.
Peekn
()
val
:=
statedb
.
GetState
(
context
.
Address
(),
x
.
Bytes
())
if
len
(
val
)
==
0
&&
len
(
y
.
Bytes
())
>
0
{
// 0 => non 0
mult
=
ethutil
.
Big3
g
=
GasStorageAdd
}
else
if
len
(
val
)
>
0
&&
len
(
y
.
Bytes
())
==
0
{
statedb
.
Refund
(
self
.
env
.
Origin
(),
GasSStoreRefund
)
statedb
.
Refund
(
self
.
env
.
Origin
(),
RefundStorage
)
mult
=
ethutil
.
Big0
g
=
GasStorageMod
}
else
{
// non 0 => non 0 (or 0 => 0)
mult
=
ethutil
.
Big1
g
=
GasStorageMod
}
gas
.
Set
(
new
(
big
.
Int
)
.
Mul
(
mult
,
GasSStore
))
case
BALANCE
:
stack
.
require
(
1
)
gas
.
Set
(
GasBalance
)
case
MSTORE
:
stack
.
require
(
2
)
gas
.
Set
(
g
)
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
u256
(
32
))
case
MLOAD
:
stack
.
require
(
1
)
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
u256
(
32
))
case
MSTORE8
:
stack
.
require
(
2
)
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
u256
(
1
))
case
RETURN
:
stack
.
require
(
2
)
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
stack
.
data
[
stack
.
Len
()
-
2
])
case
SHA3
:
stack
.
require
(
2
)
gas
.
Set
(
GasSha
)
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
stack
.
data
[
stack
.
Len
()
-
2
])
additionalGas
.
Set
(
stack
.
data
[
stack
.
Len
()
-
2
])
case
CALLDATACOPY
:
stack
.
require
(
3
)
words
:=
toWordSize
(
stack
.
data
[
stack
.
Len
()
-
2
])
gas
.
Add
(
gas
,
words
.
Mul
(
words
,
GasSha3Word
))
case
CALLDATACOPY
:
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
stack
.
data
[
stack
.
Len
()
-
3
])
additionalGas
.
Set
(
stack
.
data
[
stack
.
Len
()
-
3
])
case
CODECOPY
:
stack
.
require
(
3
)
words
:=
toWordSize
(
stack
.
data
[
stack
.
Len
()
-
3
])
gas
.
Add
(
gas
,
words
.
Mul
(
words
,
GasCopyWord
))
case
CODECOPY
:
newMemSize
=
calcMemSize
(
stack
.
Peek
(),
stack
.
data
[
stack
.
Len
()
-
3
])
additionalGas
.
Set
(
stack
.
data
[
stack
.
Len
()
-
3
])
case
EXTCODECOPY
:
stack
.
require
(
4
)
words
:=
toWordSize
(
stack
.
data
[
stack
.
Len
()
-
3
])
gas
.
Add
(
gas
,
words
.
Mul
(
words
,
GasCopyWord
))
case
EXTCODECOPY
:
newMemSize
=
calcMemSize
(
stack
.
data
[
stack
.
Len
()
-
2
],
stack
.
data
[
stack
.
Len
()
-
4
])
additionalGas
.
Set
(
stack
.
data
[
stack
.
Len
()
-
4
])
words
:=
toWordSize
(
stack
.
data
[
stack
.
Len
()
-
4
])
gas
.
Add
(
gas
,
words
.
Mul
(
words
,
GasCopyWord
))
case
CREATE
:
size
:=
new
(
big
.
Int
)
.
Set
(
stack
.
data
[
stack
.
Len
()
-
2
])
gas
.
Add
(
gas
,
size
.
Mul
(
size
,
GasCreateByte
))
case
CALL
,
CALLCODE
:
stack
.
require
(
7
)
gas
.
Set
(
GasCall
)
addStepGasUsage
(
stack
.
data
[
stack
.
Len
()
-
1
])
gas
.
Add
(
gas
,
stack
.
data
[
stack
.
Len
()
-
1
])
if
op
==
CALL
{
if
self
.
env
.
State
()
.
GetStateObject
(
stack
.
data
[
stack
.
Len
()
-
2
]
.
Bytes
())
==
nil
{
gas
.
Add
(
gas
,
GasCallNewAccount
)
}
if
len
(
stack
.
data
[
stack
.
Len
()]
.
Bytes
())
>
0
{
gas
.
Add
(
gas
,
GasCallValueTransfer
)
}
}
x
:=
calcMemSize
(
stack
.
data
[
stack
.
Len
()
-
6
],
stack
.
data
[
stack
.
Len
()
-
7
])
y
:=
calcMemSize
(
stack
.
data
[
stack
.
Len
()
-
4
],
stack
.
data
[
stack
.
Len
()
-
5
])
newMemSize
=
ethutil
.
BigMax
(
x
,
y
)
case
CREATE
:
stack
.
require
(
3
)
gas
.
Set
(
GasCreate
)
newMemSize
=
calcMemSize
(
stack
.
data
[
stack
.
Len
()
-
2
],
stack
.
data
[
stack
.
Len
()
-
3
])
}
switch
op
{
case
CALLDATACOPY
,
CODECOPY
,
EXTCODECOPY
:
additionalGas
.
Add
(
additionalGas
,
u256
(
31
))
additionalGas
.
Div
(
additionalGas
,
u256
(
32
))
addStepGasUsage
(
additionalGas
)
case
SHA3
:
additionalGas
.
Add
(
additionalGas
,
u256
(
31
))
additionalGas
.
Div
(
additionalGas
,
u256
(
32
))
additionalGas
.
Mul
(
additionalGas
,
GasSha3Byte
)
addStepGasUsage
(
additionalGas
)
}
if
newMemSize
.
Cmp
(
ethutil
.
Big0
)
>
0
{
newMemSize
.
Add
(
newMemSize
,
u256
(
31
))
newMemSize
.
Div
(
newMemSize
,
u256
(
32
))
...
...
@@ -913,10 +954,10 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
if
newMemSize
.
Cmp
(
u256
(
int64
(
mem
.
Len
())))
>
0
{
memGasUsage
:=
new
(
big
.
Int
)
.
Sub
(
newMemSize
,
u256
(
int64
(
mem
.
Len
())))
memGasUsage
.
Mul
(
GasMem
ory
,
memGasUsage
)
memGasUsage
.
Mul
(
GasMem
Word
,
memGasUsage
)
memGasUsage
.
Div
(
memGasUsage
,
u256
(
32
))
addStepGasUsage
(
memGasUsage
)
gas
.
Add
(
gas
,
memGasUsage
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment