@@ -137,6 +137,51 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, author *com
137
137
return receipt , err
138
138
}
139
139
140
+ func applyTransactionWithResult (msg types.Message , config * params.ChainConfig , bc ChainContext , author * common.Address , gp * GasPool , statedb * state.StateDB , header * types.Header , tx * types.Transaction , usedGas * uint64 , evm * vm.EVM ) (* types.Receipt , * ExecutionResult , error ) {
141
+ // Create a new context to be used in the EVM environment.
142
+ txContext := NewEVMTxContext (msg )
143
+ evm .Reset (txContext , statedb )
144
+
145
+ // Apply the transaction to the current state (included in the env).
146
+ result , err := ApplyMessage (evm , msg , gp )
147
+ if err != nil {
148
+ return nil , nil , err
149
+ }
150
+
151
+ // Update the state with pending changes.
152
+ var root []byte
153
+ if config .IsByzantium (header .Number ) {
154
+ statedb .Finalise (true )
155
+ } else {
156
+ root = statedb .IntermediateRoot (config .IsEIP158 (header .Number )).Bytes ()
157
+ }
158
+ * usedGas += result .UsedGas
159
+
160
+ // Create a new receipt for the transaction, storing the intermediate root and gas used
161
+ // by the tx.
162
+ receipt := & types.Receipt {Type : tx .Type (), PostState : root , CumulativeGasUsed : * usedGas }
163
+ if result .Failed () {
164
+ receipt .Status = types .ReceiptStatusFailed
165
+ } else {
166
+ receipt .Status = types .ReceiptStatusSuccessful
167
+ }
168
+ receipt .TxHash = tx .Hash ()
169
+ receipt .GasUsed = result .UsedGas
170
+
171
+ // If the transaction created a contract, store the creation address in the receipt.
172
+ if msg .To () == nil {
173
+ receipt .ContractAddress = crypto .CreateAddress (evm .TxContext .Origin , tx .Nonce ())
174
+ }
175
+
176
+ // Set the receipt logs and create the bloom filter.
177
+ receipt .Logs = statedb .GetLogs (tx .Hash (), header .Hash ())
178
+ receipt .Bloom = types .CreateBloom (types.Receipts {receipt })
179
+ receipt .BlockHash = header .Hash ()
180
+ receipt .BlockNumber = header .Number
181
+ receipt .TransactionIndex = uint (statedb .TxIndex ())
182
+ return receipt , result , err
183
+ }
184
+
140
185
// ApplyTransaction attempts to apply a transaction to the given state database
141
186
// and uses the input parameters for its environment. It returns the receipt
142
187
// for the transaction, gas used and an error if the transaction failed,
@@ -151,3 +196,14 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
151
196
vmenv := vm .NewEVM (blockContext , vm.TxContext {}, statedb , config , cfg )
152
197
return applyTransaction (msg , config , author , gp , statedb , header .Number , header .Hash (), tx , usedGas , vmenv )
153
198
}
199
+
200
+ func ApplyTransactionWithResult (config * params.ChainConfig , bc ChainContext , author * common.Address , gp * GasPool , statedb * state.StateDB , header * types.Header , tx * types.Transaction , usedGas * uint64 , cfg vm.Config ) (* types.Receipt , * ExecutionResult , error ) {
201
+ msg , err := tx .AsMessage (types .MakeSigner (config , header .Number ), header .BaseFee )
202
+ if err != nil {
203
+ return nil , nil , err
204
+ }
205
+ // Create a new context to be used in the EVM environment
206
+ blockContext := NewEVMBlockContext (header , bc , author )
207
+ vmenv := vm .NewEVM (blockContext , vm.TxContext {}, statedb , config , cfg )
208
+ return applyTransactionWithResult (msg , config , bc , author , gp , statedb , header , tx , usedGas , vmenv )
209
+ }
0 commit comments