public ISmartContractExecutionResult Execute(ISmartContractTransactionContext transactionContext) { this.logger.LogTrace("()"); var callDataDeserializationResult = this.serializer.Deserialize(transactionContext.ScriptPubKey.ToBytes()); // TODO Handle deserialization failure var callData = callDataDeserializationResult.Value; var gasMeter = new GasMeter(callData.GasLimit); var context = new TransactionContext( transactionContext.TransactionHash, transactionContext.BlockHeight, transactionContext.CoinbaseAddress, transactionContext.Sender, transactionContext.TxOutValue); var creation = IsCreateContract(callData); var result = creation ? this.vm.Create(gasMeter, this.stateSnapshot, callData, context) : this.vm.ExecuteMethod(gasMeter, this.stateSnapshot, callData, context); var revert = result.ExecutionException != null; var internalTransaction = this.transferProcessor.Process( this.stateSnapshot, creation ? result.NewContractAddress : callData.ContractAddress, transactionContext, result.InternalTransfers, revert); (var fee, var refundTxOuts) = this.refundProcessor.Process( callData, transactionContext.MempoolFee, transactionContext.Sender, result.GasConsumed, result.ExecutionException); var executionResult = new SmartContractExecutionResult { NewContractAddress = !revert && creation ? result.NewContractAddress : null, Exception = result.ExecutionException, GasConsumed = result.GasConsumed, Return = result.Result, InternalTransaction = internalTransaction, Fee = fee, Refunds = refundTxOuts }; if (revert) { this.logger.LogTrace("(-)[CONTRACT_EXECUTION_FAILED]"); this.stateSnapshot.Rollback(); } else { this.logger.LogTrace("(-)[CONTRACT_EXECUTION_SUCCEEDED]"); this.stateSnapshot.Commit(); } return(executionResult); }
public ISmartContractExecutionResult Execute(ISmartContractTransactionContext transactionContext) { this.logger.LogTrace("()"); // Deserialization can't fail because this has already been through SmartContractFormatRule. Result <ContractTxData> callDataDeserializationResult = this.serializer.Deserialize(transactionContext.Data); ContractTxData callData = callDataDeserializationResult.Value; var gasMeter = new GasMeter(callData.GasLimit); gasMeter.Spend((Gas)GasPriceList.BaseCost); var context = new TransactionContext( transactionContext.TransactionHash, transactionContext.BlockHeight, transactionContext.CoinbaseAddress, transactionContext.Sender, transactionContext.TxOutValue); var creation = IsCreateContract(callData); VmExecutionResult result = creation ? this.vm.Create(gasMeter, this.stateSnapshot, callData, context) : this.vm.ExecuteMethod(gasMeter, this.stateSnapshot, callData, context); var revert = result.ExecutionException != null; Transaction internalTransaction = this.transferProcessor.Process( this.stateSnapshot, creation ? result.NewContractAddress : callData.ContractAddress, transactionContext, result.InternalTransfers, revert); (Money fee, List <TxOut> refundTxOuts) = this.refundProcessor.Process( callData, transactionContext.MempoolFee, transactionContext.Sender, result.GasConsumed, result.ExecutionException); var executionResult = new SmartContractExecutionResult { NewContractAddress = !revert && creation ? result.NewContractAddress : null, To = !IsCreateContract(callData) ? callData.ContractAddress : null, Exception = result.ExecutionException, GasConsumed = result.GasConsumed, Return = result.Result, InternalTransaction = internalTransaction, Fee = fee, Refunds = refundTxOuts, Logs = result.RawLogs.ToLogs(this.contractPrimitiveSerializer) }; if (revert) { this.logger.LogTrace("(-)[CONTRACT_EXECUTION_FAILED]"); this.stateSnapshot.Rollback(); } else { this.logger.LogTrace("(-)[CONTRACT_EXECUTION_SUCCEEDED]"); this.stateSnapshot.Commit(); } return(executionResult); }