/// <summary> /// Execute the contract and add all relevant fees and refunds to the block. /// </summary> /// <remarks>TODO: At some point we need to change height to a ulong.</remarks> private IContractExecutionResult ExecuteSmartContract(TxMempoolEntry mempoolEntry) { GetSenderResult getSenderResult = this.senderRetriever.GetSender(mempoolEntry.Transaction, this.coinView, this.inBlock.Select(x => x.Transaction).ToList()); if (!getSenderResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-block-assembler-addcontracttoblock", getSenderResult.Error)); } IContractTransactionContext transactionContext = new ContractTransactionContext((ulong)this.height, this.coinbaseAddress, mempoolEntry.Fee, getSenderResult.Sender, mempoolEntry.Transaction); IContractExecutor executor = this.executorFactory.CreateExecutor(this.stateSnapshot, transactionContext); IContractExecutionResult result = executor.Execute(transactionContext); this.blockGasConsumed += result.GasConsumed; // As we're not storing receipts, can use only consensus fields. var receipt = new Receipt( new uint256(this.stateSnapshot.Root), result.GasConsumed, result.Logs.ToArray() ); this.receipts.Add(receipt); return(result); }
/// <summary> /// Execute the contract and add all relevant fees and refunds to the block. /// </summary> /// <remarks>TODO: At some point we need to change height to a ulong.</remarks> private IContractExecutionResult ExecuteSmartContract(TxMempoolEntry mempoolEntry) { // This coinview object can be altered by consensus whilst we're mining. // If this occurred, we would be mining on top of the wrong tip anyway, so // it's okay to throw a ConsensusError which is handled by the miner, and continue. GetSenderResult getSenderResult = this.senderRetriever.GetSender(mempoolEntry.Transaction, this.coinView, this.inBlock.Select(x => x.Transaction).ToList()); if (!getSenderResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-block-assembler-addcontracttoblock", getSenderResult.Error)); } IContractTransactionContext transactionContext = new ContractTransactionContext((ulong)this.height, this.coinbaseAddress, mempoolEntry.Fee, getSenderResult.Sender, mempoolEntry.Transaction); IContractExecutor executor = this.executorFactory.CreateExecutor(this.stateSnapshot, transactionContext); IContractExecutionResult result = executor.Execute(transactionContext); this.blockGasConsumed += result.GasConsumed; // As we're not storing receipts, can use only consensus fields. var receipt = new Receipt( new uint256(this.stateSnapshot.Root), result.GasConsumed, result.Logs.ToArray() ); this.receipts.Add(receipt); return(result); }
public IActionResult LocalCallSmartContractTransaction([FromBody] BuildCallContractTransactionRequest request) { if (!this.ModelState.IsValid) { return(ModelStateErrors.BuildErrorResponse(this.ModelState)); } // Rewrite the method name to a property name this.RewritePropertyGetterName(request); BuildCallContractTransactionResponse response = this.smartContractTransactionService.BuildCallTx(request); Transaction transaction = this.network.CreateTransaction(response.Hex); var transactionContext = new ContractTransactionContext( (ulong)this.chain.Height, uint160.Zero, 0, // Safe to set this to 0 here, it's only used for the refund which we do not create when executing locally request.Sender.ToUint160(this.network), transaction); ILocalExecutionResult result = this.localExecutor.Execute(transactionContext); return(Json(result)); }
/// <summary> /// Execute the contract and add all relevant fees and refunds to the block. /// </summary> /// <remarks>TODO: At some point we need to change height to a ulong.</remarks> /// <param name="mempoolEntry">The mempool entry containing the smart contract transaction.</param> private IContractExecutionResult ExecuteSmartContract(TxMempoolEntry mempoolEntry) { // This coinview object can be altered by consensus whilst we're mining. // If this occurred, we would be mining on top of the wrong tip anyway, so // it's okay to throw a ConsensusError which is handled by the miner, and continue. GetSenderResult getSenderResult = this.senderRetriever.GetSender(mempoolEntry.Transaction, this.coinView, this.inBlock.Select(x => x.Transaction).ToList()); if (!getSenderResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-block-assembler-addcontracttoblock", getSenderResult.Error)); } IContractTransactionContext transactionContext = new ContractTransactionContext((ulong)this.height, this.coinbaseAddress, mempoolEntry.Fee, getSenderResult.Sender, mempoolEntry.Transaction); IContractExecutor executor = this.executorFactory.CreateExecutor(this.stateSnapshot, transactionContext); IContractExecutionResult result = executor.Execute(transactionContext); Result <ContractTxData> deserializedCallData = this.callDataSerializer.Deserialize(transactionContext.Data); this.blockGasConsumed += result.GasConsumed; // Store all fields. We will reuse these in CoinviewRule. var receipt = new Receipt( new uint256(this.stateSnapshot.Root), result.GasConsumed, result.Logs.ToArray(), transactionContext.TransactionHash, transactionContext.Sender, result.To, result.NewContractAddress, !result.Revert, result.Return?.ToString(), result.ErrorMessage, deserializedCallData.Value.GasPrice, transactionContext.TxOutValue, deserializedCallData.Value.IsCreateContract ? null : deserializedCallData.Value.MethodName); this.receipts.Add(receipt); return(result); }