@@ -145,6 +145,51 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
145145 return receipt , err
146146}
147147
148+ 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 ) {
149+ // Create a new context to be used in the EVM environment.
150+ txContext := NewEVMTxContext (msg )
151+ evm .Reset (txContext , statedb )
152+
153+ // Apply the transaction to the current state (included in the env).
154+ result , err := ApplyMessage (evm , msg , gp )
155+ if err != nil {
156+ return nil , nil , err
157+ }
158+
159+ // Update the state with pending changes.
160+ var root []byte
161+ if config .IsByzantium (header .Number ) {
162+ statedb .Finalise (true )
163+ } else {
164+ root = statedb .IntermediateRoot (config .IsEIP158 (header .Number )).Bytes ()
165+ }
166+ * usedGas += result .UsedGas
167+
168+ // Create a new receipt for the transaction, storing the intermediate root and gas used
169+ // by the tx.
170+ receipt := & types.Receipt {Type : tx .Type (), PostState : root , CumulativeGasUsed : * usedGas }
171+ if result .Failed () {
172+ receipt .Status = types .ReceiptStatusFailed
173+ } else {
174+ receipt .Status = types .ReceiptStatusSuccessful
175+ }
176+ receipt .TxHash = tx .Hash ()
177+ receipt .GasUsed = result .UsedGas
178+
179+ // If the transaction created a contract, store the creation address in the receipt.
180+ if msg .To () == nil {
181+ receipt .ContractAddress = crypto .CreateAddress (evm .TxContext .Origin , tx .Nonce ())
182+ }
183+
184+ // Set the receipt logs and create the bloom filter.
185+ receipt .Logs = statedb .GetLogs (tx .Hash (), header .Hash ())
186+ receipt .Bloom = types .CreateBloom (types.Receipts {receipt })
187+ receipt .BlockHash = header .Hash ()
188+ receipt .BlockNumber = header .Number
189+ receipt .TransactionIndex = uint (statedb .TxIndex ())
190+ return receipt , result , err
191+ }
192+
148193// ApplyTransaction attempts to apply a transaction to the given state database
149194// and uses the input parameters for its environment. It returns the receipt
150195// for the transaction, gas used and an error if the transaction failed,
@@ -159,3 +204,14 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
159204 vmenv := vm .NewEVM (blockContext , vm.TxContext {}, statedb , config , cfg )
160205 return applyTransaction (msg , config , gp , statedb , header .Number , header .Hash (), tx , usedGas , vmenv )
161206}
207+
208+ 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 ) {
209+ msg , err := tx .AsMessage (types .MakeSigner (config , header .Number ), header .BaseFee )
210+ if err != nil {
211+ return nil , nil , err
212+ }
213+ // Create a new context to be used in the EVM environment
214+ blockContext := NewEVMBlockContext (header , bc , author )
215+ vmenv := vm .NewEVM (blockContext , vm.TxContext {}, statedb , config , cfg )
216+ return applyTransactionWithResult (msg , config , bc , author , gp , statedb , header , tx , usedGas , vmenv )
217+ }
0 commit comments