예제 #1
0
        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 });
        }
예제 #2
0
        public void InvalidContractNameTest()
        {
            var function = new ContractFunction()
            {
                Name = "123"
            };

            function.GenerateCode(new Indentation());
        }
예제 #3
0
        public void EmptyContractVisibilityTest()
        {
            var function = new ContractFunction()
            {
                Name = "Test"
            };

            function.GenerateCode(new Indentation());
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        // 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);
        }
예제 #6
0
        public void ModificationTypeXorIsPayableTest2()
        {
            var function = new ContractFunction()
            {
                Name             = "Test",
                Visibility       = Visibility.Public,
                ModificationType = ModificationType.View,
                IsPayable        = true
            };

            function.GenerateCode(new Indentation());
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
 /// <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();
 }
예제 #9
0
    /// <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);
    }
예제 #10
0
    /// <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);
    }
예제 #11
0
    /// <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);
    }
예제 #12
0
        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()));
        }
예제 #13
0
 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})" });
        }
예제 #15
0
        public void EmptyContractNameTest()
        {
            var function = new ContractFunction();

            function.GenerateCode(new Indentation());
        }
예제 #16
0
        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));
        }
예제 #17
0
 public void GenerateCallCodeTest(ContractFunction f, string expected)
 {
     System.Diagnostics.Contracts.Contract.Requires(f != null);
     Assert.AreEqual(expected, f.GenerateCallCode());
 }