static object[] GenerateRow(string parametersListCode, string name, string instructionsListCode, Visibility?visibility, Modifier m, string modifierParametersListCode, bool anyModifierParameter, SolidityType?returningType, ModificationType modificationType, bool isPayable, string expected) { var indentation = new Indentation(); var parametersListMock = parametersListCode != null?mockHelper.PrepareMock(parametersListCode, true, true) : null; var instructionsListMock = instructionsListCode != null?instructionsListMockHelper.PrepareMock(instructionsListCode, false, !string.IsNullOrWhiteSpace(instructionsListCode), indentation.GetIndentationWithIncrementedLevel()) : null; var ma = m != null ? new ModifierAppliance() { ModifierToApply = m, Parameters = callingParametersMockHelper.PrepareMock(modifierParametersListCode, anyModifierParameter) } : null; var f = new ContractFunction() { Instructions = instructionsListMock, Name = name, Parameters = parametersListMock, Visibility = visibility, Modifier = ma, ReturningType = returningType, ModificationType = modificationType, IsPayable = isPayable }; return(new object[] { f, indentation, expected }); }
public void InvalidContractNameTest() { var function = new ContractFunction() { Name = "123" }; function.GenerateCode(new Indentation()); }
public void EmptyContractVisibilityTest() { var function = new ContractFunction() { Name = "Test" }; function.GenerateCode(new Indentation()); }
/// <summary> /// Estimates the gas limit of a <see cref="ContractFunction"/>. /// </summary> /// <typeparam name="TFunc"> The <see cref="ContractFunction"/> to estimate the gas limit for. </typeparam> /// <param name="contractAddress"> The address of the contract function to estimate. </param> /// <param name="callerAddress"> The address of the sender. </param> /// <param name="input"> The input parameters of the function. </param> public static EthCallPromise <BigInteger> EstimateContractGasLimit <TFunc>( string contractAddress, string callerAddress, params object[] input) where TFunc : ContractFunction { var promise = new EthCallPromise <BigInteger>(); _EstimateGasLimitCoroutine(promise, ContractFunction.CreateFunction <TFunc>(callerAddress, input).CreateTransactionInput(contractAddress), true).StartCoroutine(); return(promise); }
// Note: when contract uses blokchain state as context, need to pass it in. public static bool ExecuteContract( byte[] contractHash, ContractFunction contractFunction, byte[] message, out Types.Transaction transaction, UtxoLookup UtxoLookup, bool isWitness) { var contractFunctionInput = new ContractFunctionInput( message, contractHash, UtxoLookup ); TransactionSkeleton transactionSkeleton = null; transaction = null; try { var serializer = new ContractExamples.FStarCompatibility.DataSerializer(Consensus.Serialization.context); Consensus.Serialization.context.Serializers.RegisterOverride(serializer); var result = contractFunction.Invoke(contractFunctionInput); if (result.IsError) { BlockChainTrace.Information("Contract resulted in error: " + result.ErrorValue); return(false); } transactionSkeleton = result.ResultValue; } catch (Exception e) { BlockChainTrace.Error("Error executing contract", e); return(false); } if (transactionSkeleton == null) { return(false); } transaction = new Types.Transaction( Tests.tx.version, transactionSkeleton.Item1, ListModule.OfSeq(isWitness ? new byte[][] { message } : new byte[][] { }), transactionSkeleton.Item2, FSharpOption <Types.ExtendedContract> .None //TODO: get from txSkeleton.Item3 ); return(true); }
public void ModificationTypeXorIsPayableTest2() { var function = new ContractFunction() { Name = "Test", Visibility = Visibility.Public, ModificationType = ModificationType.View, IsPayable = true }; function.GenerateCode(new Indentation()); }
/// <summary> /// Coroutine which queries some data from an ethereum smart contract. /// </summary> /// <typeparam name="TFunc"> The <see cref="ContractFunction"/> of the smart contract to execute which will return us some data. </typeparam> /// <typeparam name="TOut"> The <see cref="IFunctionOutputDTO"/> which represents the data which was returned from the <see cref="ContractFunction"/>. </typeparam> /// <param name="promise"> Promise of eventually returning the data from the contract query. </param> /// <param name="contractAddress"> The contract address to execute the <see cref="ContractFunction"/> on. </param> /// <param name="senderAddress"> The address of the sender requesting this data. </param> /// <param name="functionInput"> The input parameters of the <see cref="ContractFunction"/>. </param> private static IEnumerator _QueryContractCoroutine <TFunc, TOut>( EthCallPromise <TOut> promise, string contractAddress, string senderAddress, params object[] functionInput) where TFunc : ContractFunction where TOut : IFunctionOutputDTO, new() { var queryRequest = new QueryUnityRequest <TFunc, TOut>(EthereumNetworkManager.CurrentNetwork.NetworkUrl, senderAddress); yield return(queryRequest.Query(ContractFunction.CreateFunction <TFunc>(functionInput), contractAddress)); promise.Build(queryRequest, () => queryRequest.Result); }
/// <summary> /// Sends a message to an ethereum smart contract with the intent to change a part of the contract on the blockchain. /// </summary> /// <typeparam name="TFunc"> The <see cref="ContractFunction"/> to execute on the blockchain given the contract address. </typeparam> /// <param name="contractAddress"> The contract address to execute the <see cref="ContractFunction"/> on. </param> /// <param name="message"> The message representing the transaction. </param> /// <param name="signedUnityRequest"> The <see cref="TransactionSignedUnityRequest"/> to use to send the message. </param> /// <param name="gasPrice"> The <see cref="HexBigInteger"/> gas price to use with the transaction. </param> /// <param name="gasLimit"> The <see cref="HexBigInteger"/> gas limit to use with the transaction. </param> /// <param name="functionInput"> The input parameters of the <see cref="ContractFunction"/>. </param> /// <returns> Promise of the transaction result of sending the contract message. </returns> public static void SendContractMessage <TFunc>( string contractAddress, string message, TransactionSignedUnityRequest signedUnityRequest, HexBigInteger gasPrice, HexBigInteger gasLimit, params object[] functionInput) where TFunc : ContractFunction { _SendContractMessageCoroutine( message, ContractFunction.CreateFunction <TFunc>(gasPrice, gasLimit, functionInput).CreateTransactionInput(contractAddress), signedUnityRequest).StartCoroutine(); }
/// <summary> /// Releases some purpose from the Hodler smart contract. /// </summary> /// <param name="userWalletManager"> The class managing the wallet. </param> /// <param name="gasLimit"> The gas limit to send with the transaction. </param> /// <param name="gasPrice"> The gas price to send with the transaction. </param> /// <param name="id"> The id of the locked purpose item. </param> /// <param name="amountToRelease"> The amount of purpose that will be released. </param> public void Release(UserWalletManager userWalletManager, HexBigInteger gasLimit, HexBigInteger gasPrice, BigInteger id, decimal amountToRelease) { var transactionInput = ContractFunction.CreateFunction <Messages.Release>( userWalletManager, gasPrice, gasLimit, id).CreateTransactionInput(ContractAddress); userWalletManager.SignTransaction <ConfirmReleasePopup>( request => ContractUtils.SendContractMessage("Releasing PRPS", transactionInput, request), gasLimit, gasPrice, 0, ContractAddress, transactionInput.Data, amountToRelease); }
/// <summary> /// Locks a certain amount of purpose into the Hodler smart contract. /// </summary> /// <param name="userWalletManager"> The class managing the wallet. </param> /// <param name="gasLimit"> The gas limit to send with the transaction. </param> /// <param name="gasPrice"> The gas price to send with the transaction. </param> /// <param name="id"> The id of the lock function call. </param> /// <param name="value"> The amount of purpose to lock. </param> /// <param name="monthsToLock"> How many months the purpose should be locked for. </param> public void Hodl(UserWalletManager userWalletManager, HexBigInteger gasLimit, HexBigInteger gasPrice, BigInteger id, decimal value, int monthsToLock) { var transactionInput = ContractFunction.CreateFunction <Messages.Hodl>( userWalletManager, gasPrice, gasLimit, id, SolidityUtils.ConvertToUInt(value, 18), new BigInteger(monthsToLock)).CreateTransactionInput(ContractAddress); userWalletManager.SignTransaction <ConfirmLockPopup>( request => ContractUtils.SendContractMessage("Locking PRPS", transactionInput, request), gasLimit, gasPrice, 0, ContractAddress, transactionInput.Data, monthsToLock, value); }
/// <summary> /// Transfers a certain number of tokens of this contract from a wallet to another address. /// </summary> /// <param name="userWalletManager"> The wallet to transfer the tokens from. </param> /// <param name="gasLimit"> The gas limit to use when sending the tokens. </param> /// <param name="gasPrice"> The gas price to use when sending the tokens. </param> /// <param name="address"> The address to transfer the tokens to. </param> /// <param name="amount"> The amount of tokens to transfer. </param> public void Transfer(UserWalletManager userWalletManager, HexBigInteger gasLimit, HexBigInteger gasPrice, string address, decimal amount) { var transactionInput = ContractFunction.CreateFunction <Messages.Transfer>( userWalletManager, gasPrice, gasLimit, address, SolidityUtils.ConvertToUInt(amount, Decimals.Value)).CreateTransactionInput(ContractAddress); userWalletManager.SignTransaction <ConfirmTransactionPopup>( request => ContractUtils.SendContractMessage($"Sending {Symbol}", transactionInput, request), gasLimit, gasPrice, 0, ContractAddress, transactionInput.Data, address, ContractAddress, amount, Symbol); }
static void Main(string[] args) { var boolType = SolidityType.Bool; var intType = SolidityType.Int; var propertyName = "PropertyName1"; var propertyName2 = "PropertyName2"; var propertyName3 = "PropertyName3"; var pr1 = new ContractProperty() { Variable = PrepareVariable(propertyName, boolType), Visibility = Visibility.Public }; var pr2 = new ContractProperty() { Variable = PrepareVariable(propertyName2, intType), Visibility = Visibility.Private }; var pr3 = new ContractProperty() { Variable = PrepareVariable(propertyName3, boolType), Visibility = Visibility.Public }; var properties = new List <ContractProperty>() { pr1, pr2, pr3 }; var eventName = "EventName1"; var eventName2 = "EventName2"; var eventName3 = "EventName3"; var epl = new ParametersList() { Parameters = new List <Variable>() { PrepareVariable("ep1", boolType), PrepareVariable("ep2", intType) } }; var epl2 = new ParametersList() { Parameters = new List <Variable>() { PrepareVariable("ep1", boolType) } }; var epl3 = new ParametersList() { Parameters = new List <Variable>() { PrepareVariable("ep1", intType) } }; var e1 = new ContractEvent() { Name = eventName, Parameters = epl }; var e2 = new ContractEvent() { Name = eventName2, Parameters = epl2 }; var e3 = new ContractEvent() { Name = eventName3, Parameters = epl3 }; var events = new List <ContractEvent>() { e1, e2, e3 }; var name1 = "_p"; var name2 = "_q"; var name3 = "_r"; var name4 = "v"; var p1 = PrepareVariable(name1, boolType); var p2 = PrepareVariable(name2, boolType); var p3 = PrepareVariable(name3, boolType); var v = PrepareVariable(name4, boolType); var pl = new ParametersList() { Parameters = new List <Variable>() { p1, p2 } }; var pl2 = new ParametersList() { Parameters = new List <Variable>() { p1, p2, p3 } }; var cpl = new CallingParametersList() { Parameters = new List <IAssignable>() { p1, p2 } }; var cpl2 = new CallingParametersList() { Parameters = new List <IAssignable>() { p1, p2, p3 } }; var d = new Declaration() { Variable = v }; var op = new Operation() { LeftSide = p1, Operator = OperationOperator.OR, RightSide = p2 }; var instruction = new Assignment() { Destination = d, Source = op }; var ao = new Operation() { LeftSide = v, Operator = OperationOperator.Negation }; var instruction2 = new Assignment() { Destination = v, Source = ao }; var instructions = new InstructionsList(); instructions.AppendInstruction(instruction); instructions.AppendInstruction(instruction2); var c = new Constructor() { Visibility = Visibility.Public, Parameters = pl, Instructions = instructions }; var functionInstructions = new InstructionsList(); functionInstructions.AppendInstruction(instruction); var aof = new Operation() { LeftSide = v, Operator = OperationOperator.AND, RightSide = p3 }; var instruction3 = new Assignment() { Destination = v, Source = aof }; functionInstructions.AppendInstruction(instruction3); var function = new ContractFunction() { Name = "TestFunction", Visibility = Visibility.Public, Parameters = pl2, Instructions = functionInstructions }; var fp1 = PrepareVariable(name1, intType); var fp2 = PrepareVariable(name2, intType); var fp3 = PrepareVariable(name3, intType); var fv = PrepareVariable(name4, intType); var fpl = new ParametersList() { Parameters = new List <Variable>() { fp1, fp2, fp3 } }; var fd = new Declaration() { Variable = fv }; var fop = new Operation() { LeftSide = p1, Operator = OperationOperator.Plus, RightSide = p2 }; var finstruction = new Assignment() { Destination = fd, Source = fop }; var fao = new Operation() { LeftSide = v, Operator = OperationOperator.Multiply, RightSide = fp3 }; var finstruction2 = new Assignment() { Destination = pr2, Source = fao }; var finstructions = new InstructionsList(); finstructions.AppendInstruction(finstruction); finstructions.AppendInstruction(finstruction2); var function2 = new ContractFunction() { Name = "TestFunction2", Visibility = Visibility.External, Parameters = fpl, Instructions = finstructions }; var trueInstructions = new InstructionsList(); var falseInstructions = new InstructionsList(); trueInstructions.AppendInstruction( new FunctionCall() { FunctionToCall = function, Parameters = cpl2 } ); var ecpl = new CallingParametersList() { Parameters = new List <IAssignable>() { p1 } }; falseInstructions.AppendInstruction( new EventCall() { EventToCall = e2, Parameters = ecpl } ); var newFInstructions = new InstructionsList(); var condOp = new Operation() { LeftSide = p1, Operator = OperationOperator.Negation }; var cond = new Condition() { ConditionOperation = condOp }; var ifStatement = new IfStatement() { Condition = cond, TrueInstructions = trueInstructions, FalseInstructions = falseInstructions }; newFInstructions.AppendInstruction(ifStatement); var loopVariable = PrepareVariable("loopVariable", intType); var declaration = new Declaration() { Variable = loopVariable }; var assignment = new Assignment() { Destination = declaration, Source = new ConstantValue() { Value = "0" } }; var condOperation = new Operation() { LeftSide = loopVariable, Operator = OperationOperator.NotEquals, RightSide = new ConstantValue() { Value = "1" } }; var breakCondition = new Condition() { ConditionOperation = condOperation }; var stepOp = new Operation() { LeftSide = loopVariable, Operator = OperationOperator.Plus, RightSide = new ConstantValue() { Value = "1" } }; var stepInstruction = new Assignment() { Destination = loopVariable, Source = stepOp }; var loopInstructions = new InstructionsList(); var cple = new CallingParametersList() { Parameters = new List <IAssignable>() { loopVariable } }; loopInstructions.AppendInstruction( new EventCall() { EventToCall = e3, Parameters = cple } ); var loop = new ContractLoop() { InitialAssignment = assignment, BreakCondition = breakCondition, StepInstruction = stepInstruction, Instructions = loopInstructions }; newFInstructions.AppendInstruction(loop); var function3 = new ContractFunction() { Name = "NewFunction", Visibility = Visibility.Public, Parameters = pl2, Instructions = newFInstructions }; var functions = new List <ContractFunction>() { function, function2, function3 }; string contractName = "TestContract"; Contract contract = new Contract() { Name = contractName, Constructor = c, Functions = functions, Events = events, Properties = properties }; Console.WriteLine(contract.GenerateCode(new Indentation())); }
public void GenerateCodeTest(ContractFunction function, Indentation indentation, string expected) { System.Diagnostics.Contracts.Contract.Requires(function != null); Assert.AreEqual(expected, function.GenerateCode(indentation)); }
static IEnumerable <object[]> GetDataForGenerateCodeTest() { string funcName = "functionName"; var function = new ContractFunction() { Name = funcName }; var functionCall = new FunctionCall() { FunctionToCall = function }; yield return(new object[] { functionCall, $"{funcName}()" }); string eventName = "eventName"; var contractEvent = new ContractEvent() { Name = eventName }; var eventCall = new EventCall() { EventToCall = contractEvent }; yield return(new object[] { eventCall, $"emit {eventName}()" }); string modifierName = "modifierName"; var modifier = new Modifier() { Name = modifierName }; var modifierAppliance = new ModifierAppliance() { ModifierToApply = modifier }; yield return(new object[] { modifierAppliance, $"{modifierName}()" }); var variables = new List <IAssignable>(); var parameters = new CallingParametersList() { Parameters = variables }; functionCall.Parameters = parameters; yield return(new object[] { functionCall, $"{funcName}()" }); eventCall.Parameters = parameters; yield return(new object[] { eventCall, $"emit {eventName}()" }); modifierAppliance.Parameters = parameters; yield return(new object[] { modifierAppliance, $"{modifierName}()" }); var vName1 = "vName"; var v1 = new Variable() { Name = vName1, Type = SolidityType.Bool }; parameters.Parameters.Add(v1); yield return(new object[] { eventCall, $"emit {eventName}({vName1})" }); yield return(new object[] { functionCall, $"{funcName}({vName1})" }); yield return(new object[] { modifierAppliance, $"{modifierName}({vName1})" }); var vName2 = "vName2"; var v2 = new Variable() { Name = vName2, Type = SolidityType.Bool }; parameters.Parameters.Add(v2); yield return(new object[] { eventCall, $"emit {eventName}({vName1}, {vName2})" }); yield return(new object[] { functionCall, $"{funcName}({vName1}, {vName2})" }); yield return(new object[] { modifierAppliance, $"{modifierName}({vName1}, {vName2})" }); }
public void EmptyContractNameTest() { var function = new ContractFunction(); function.GenerateCode(new Indentation()); }
public static bool IsValidAutoTx(TransactionValidation.PointedTransaction ptx, UtxoLookup UtxoLookup, byte[] contractHash, ContractFunction contractFunction) { var isWitness = false; var witnessIdx = -1; byte[] message = null; for (var i = 0; i < ptx.witnesses.Length; i++) { if (ptx.witnesses[i].Length > 0) { witnessIdx = i; } } if (witnessIdx == 0) { message = ptx.witnesses[0]; } else if (witnessIdx == -1) { var contractLock = ptx.pInputs[0].Item2.@lock as Types.OutputLock.ContractLock; if (contractLock == null) { BlockChainTrace.Information("expected ContractLock, tx invalid"); return(false); } message = contractLock.data; } isWitness = witnessIdx == 0; Types.Transaction tx; var isExecutionSuccessful = ExecuteContract( contractHash, contractFunction, message, out tx, UtxoLookup, isWitness ); return(isExecutionSuccessful && tx != null && TransactionValidation.unpoint(ptx).Equals(tx)); }
public void GenerateCallCodeTest(ContractFunction f, string expected) { System.Diagnostics.Contracts.Contract.Requires(f != null); Assert.AreEqual(expected, f.GenerateCallCode()); }