@@ -137,6 +137,51 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, author *com
137137 return receipt , err
138138}
139139
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+
140185// ApplyTransaction attempts to apply a transaction to the given state database
141186// and uses the input parameters for its environment. It returns the receipt
142187// 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
151196 vmenv := vm .NewEVM (blockContext , vm.TxContext {}, statedb , config , cfg )
152197 return applyTransaction (msg , config , author , gp , statedb , header .Number , header .Hash (), tx , usedGas , vmenv )
153198}
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