public override Task RunAsync(RuleContext context) { Block block = context.ValidationContext.BlockToValidate; IEnumerable <Transaction> opSpendTransactions = block.Transactions.Where(tx => tx.IsSmartContractSpendTransaction()); foreach (Transaction opSpendTransaction in opSpendTransactions) { var thisIndex = block.Transactions.IndexOf(opSpendTransaction); if (thisIndex <= 0) { this.Throw(); } ; Transaction previousTransaction = block.Transactions[thisIndex - 1]; // This previously would only check that the contract was a call. However we also have to check for create as inside the constructor // we could make a call to another contract and that could send funds! var previousWasOpCall = previousTransaction.Outputs.Any(o => SmartContractScript.IsSmartContractExec(o.ScriptPubKey)); if (!previousWasOpCall) { this.Throw(); } } return(Task.CompletedTask); }
private void CheckTransaction(Transaction transaction) { var smartContractExecCount = transaction.Outputs.Count(o => SmartContractScript.IsSmartContractExec(o.ScriptPubKey)); if (smartContractExecCount > 1) { new ConsensusError("multiple-smartcontractexec-outputs", "transaction contains multiple smartcontractexec outputs").Throw(); } }