public static InvocationResult CallSystemContract(SystemContractExecutionFrame currentFrame, UInt160 contractAddress, UInt160 sender, string methodSignature, params dynamic[] values) { var context = currentFrame.InvocationContext.NextContext(sender); var input = ContractEncoder.Encode(methodSignature, values); // TODO: pass correct gas amount return(ContractInvoker.Invoke(contractAddress, context, input, 100_000_000)); }
private OperatingError _InvokeContract( UInt160 addressTo, byte[] input, TransactionReceipt receipt, IBlockchainSnapshot snapshot, bool isSystemContract ) { var transaction = receipt.Transaction; var context = new InvocationContext(receipt.Transaction.From, snapshot, receipt); try { if (receipt.GasUsed > transaction.GasLimit) { return(OperatingError.OutOfGas); } var result = ContractInvoker.Invoke(addressTo, context, input, transaction.GasLimit - receipt.GasUsed); receipt.GasUsed += result.GasUsed; if (result.Status != ExecutionStatus.Ok) { return(OperatingError.ContractFailed); } if (receipt.GasUsed > transaction.GasLimit) { return(OperatingError.OutOfGas); } /* this OnSystemContractInvoked is useful for internal communication (for example - during keyGeneration) */ if (isSystemContract) { OnSystemContractInvoked?.Invoke(this, context); } return(OperatingError.Ok); } catch (OutOfGasException e) { receipt.GasUsed += e.GasUsed; } catch (Exception e) { Logger.LogWarning($"Failed contract execution: {e}"); return(OperatingError.InvalidContract); } return(OperatingError.OutOfGas); }