How to take user input in solidity? - solidity

I am trying to take an user input and add that input to a array in solidity, this thing should be added in an ERC-721 smart contract.
I tried to take input as a string, and store it. While it is having compilation error.

Related

Is it a good practice the attach an event related parameter to an object's model as a variable?

This is about an API handling the validation during saving an object. Which means that the front-end client sends a request to the API to a specific end point, then on the back-end the API creates a new object if the right conditions are meet.
Right now the regular method that we use is that the models has a ruleset for each fields and then the validation is invoked when the save function is invoked, but technically the validation is done right before the object is saved into the database.
Then during today's code review I came across a solution which I wasn't sure if it's a good practice or not. And it was about that the front-end must send a specific parameter to the API every time. This is because other APIs are using our API as well, and we needed to know if the request was sent as and API request or a browser request. If this parameter is present then we want to execute an extra validation function on a specific field.
(1)If I would have to implement it, then I would check the incoming parameter in the service handler or in the controller level, and if I got one, I would invoke the validation right away, and if it fails I would throw an error.
(2)The implementation I saw however adds an extra variable to the model, and sets the model variable when there is an incoming parameter, then validates only when the save function is invoked on the object(which first validates the ruleset defined on the object fields, then saves the object into the database)
So my problem with (2) is that the object now grown bigger with an extra variable that is only related to a specific event. So I would say it's better to implement (1). But (2) also has an advantage, and that is when you create the object on different end point by parsing the parameters, then the validation will work there as well, even if the developer forget to update the code there.
Now this may seems like a silly question because, why would I care about just 1 extra variable, but this is like a bedrock of something good or bad. So if I say this is ok, then from now on the models will start growing with extra variables that are only related to specific events, which I think should be handled on the controller/service handler level. On the other hand the code would be more reliable if it's not the developer who should remember all the 6712537 functionalities and keep them in mind when makes some changes somewhere. Let's say all the devs will get heart attack tomorrow from the excitement of an amazing discovery, and a new developer has to work on the project while he doesn't know about these small details, and then he has to change something on the code that is related to this functionality - so that new feature should be supported by this old one as well.
So my question is if is there any good practice on this, and what do you think what would be the best approach?
So I spent some time on thinking on the solution, and I think the best is to have an array of acceptable trigger variables in the model class. Then when the parameters are passed to the model on the controller level, then the loader function can be modified that it takes the trigger variables from the parameters and save it in the model's associative array variable that stores the trigger variables.
By default this array is empty, and it doesn't matter how much new variables are needed to be created, it will only contain the necessary ones when those are used.
Then of course the loader function needs to be modified in a way that it can filter out the non trigger variables as well as it is done for the regular fields, and there can be even a rule set of validation on the trigger variables if necessary.
So this solves the problem with overgrowing the object with unnecessary variables and the centralized validation part, because now the validation can be always done in the model instead of the controller.
And since the loader function is modified to store the trigger variables in the model's trigger variables array variable, the developer never has to remember that this functionality was created. Which is good, because in the future when he creates a new related function or end point that should handle object creation, he will not miss it to validate it against the old functionality, because the the loader function that he modified in the past like this will handle it for him.
It needs to be noted tho, that since the loader function doesn't differentiate between the parameters, and where to load them other then checking the names of the parameters with the filter functions, these parameter names should be identical from each other, otherwise a buggy functionality can be created accidentally. Like if you forget that a model attribute with the same name was used, then you can accidentally trigger an event that was programmed to be triggered if the trigger variable with the same name is present. However this can be solved by prefixing the trigger variables for example.

BEP-20 Contract no deploy public view functions

I am studying how to make BEP-20 tokens. For this I copied the following contract in remix to be able to study it:
Contract in BscScan
If I copy the whole file and compile it in Remix, when I deploy it it doesn't show me any getters. No public view function appears. If I look at the contract displayed on the testnet, it doesn't have any supply of tokens either.
I separated the files and libraries for a better reading. And it is then, when I try to display it, that I get the following error:
VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
It gives me the feeling that this contract does not generate the tokens ... What am I wrong?
I managed to fix the problem. As I suspected, in order to deploy the contract I have to remove everything related to uniswap and cakeswap. This displays the contract correctly.
If you wanted to deploy the contract with the uniswap interfaces in injected web3, you would need the uniswap testnet.
I found a test address for cake here:
Binance Smart change tesnet

Parse Telegram JSON message by line break

I'd like to remove the line breaks from the telegram text message using MQL4 coding. I'd like to convert the text to a format that MT4 can use to place a trade.
The issue is that the telegram bot is reading the chat and the text is converted to a one-liner with the \n separator. I need to split the different parts of the message into separate Int/Str/Double, etc. so that I can use them to place the trade using MQL4 code.
The message format is as follows:
"text":"XRPUSD\nBUYLIMIT\n0.15010\nSL 0.18000\nTP 0.14000"
This message comes in as msg.message_text but I don't see the actual message unless I use Postman. I just know the format from a JSON converter library.
Again, I need to split the different parts of the message into separate Int/Str/Double, etc, so that I can use them to place the trade using MQL4 code.
Hopefully, I am asking and presenting the data in a manner that makes sense. Please let me know.
Thanks
I think you can use StringReplace method
Like this
string text="XRPUSD\nBUYLIMIT\n0.15010\nSL 0.18000\nTP 0.14000";
int replaced=StringReplace(text,"\n","/");
Print("Replaced: ", replaced,". Result=",text);

WF4 Argument as Property

My scenario is the following:
I have a workflow (lets call it customActivity1) that do the basic actions for my system. I also have another workflow (customActivity2) that uses customActivity1 and do higher level actions. When I call customActivity1, I must pass on a few parameters, like Boolean or String values. I want to show some of these parameters as a checkbox or combobox (so the developer of customActivity2 can pass on only valid values) and found out that I can do that by setting the argument as PROPERTY (instead of In).
By doing a research, I also found out that you can’t directly use this argument in expressions, so I keep getting errors on my customActivity1.
That said and knowing that I need to narrow what the designer can pass on, how could I do that without using an activity designer or where could I find an answer?
I also attached two pictures, one of what I need and the other of the error I’m getting.
Thanks in advance.
The reason an InArgument only shows you a text field instead of a checkbox is because they are expressions not literal values. There is still type checking though, if you enter the value 1 you get the error message that an integer cannot be converted into a boolean.
You cannot do this. You can only bind to InArguments.
If you bind an InArgument and look at the xaml, you'll see something like this:
<p1:MyActivity MyInArgument="[BoundValue]" ...
The Workflow Runtime knows how to handle these. It doesn't know how to handle binding POCO properties.
If you want to model data flow but want to have a different user experience in the property grid I recommed using arguments (as they convey data flow semantics) and customizing the property grid for those arguments. There is a sample that demonstrates how to do this in the WF4 samples (sample readme available at http://msdn.microsoft.com/en-us/library/ee834515.aspx)

Is it better create a library with several functions or create classes?

I'm developing a software to comunicate with a device.
The software will send commands for the device. The device has to answer using the protocol below:
<STX><STX><COMMAND>[<DATA_1><DATA_2>...<DATA_N>]<CHKSUM><ETX>
where:
<STX> is the Start of TeXt (0x55);
<COMMAND> can be 0x01 for read, 0x02 for write, etc;
<DATA> is any value;
<CHKSUM> is the checksum;
<ETX> is the End of TeXt (0x04).
So, I have to validate the received data.
Then, the received data:
cannot be empty;
must have 3 or more characters;
must have an header in the first two characters of the string data;
must have a "footer" in the last character of the string data;
must hava a valid CheckSum.
If the answer is valid, then I can handle the data. But before I'll have to extract this data from the response received.
Ok, this is a relatively easy task. Beforetime I would do it on a procedural way, using only one function and putting many if's.
Now I'm studying more about good programming practices, things seem to be getting harder to do.
To validate the device answer, is better create a class "ValidateReceivedData" for example and pass the received data in the constructor of this class? And then create a public method called "IsReceivedDataValid" that check all steps given above?
Or maybe would be better create a library with with several functions to validate the received data?
I'd like to use unit test too.
As I said before, I'm studying more to make better code. But I realize that I'm spending more time now to code than before. And there are too many questions that are arising, but in my view they seem easy to solve, but I'm not getting.
For what it's worth, I've done this sort of thing before using object-oriented design. Here's a high level possibility for your design:
ProtocolParser class:
Takes a SerialPort object, or equivalent, in the constructor and listens to it for incoming bytes
Passes received bytes to OnByteReceived, which implements the protocol-specific state machine (with states like Unknown, Stx1Received, Stx2Received, ..., CkSumReceived).
After an entire good message is received, creates an object of type Packet, which accepts a byte list in its constructor. It then raises an event PacketReceived, passing the Packet as an argument.
If a bad byte is received, it raises an event BadDataReceived and passes the bad data (for logging/debugging purposes, perhaps).
Packet class:
Takes a list/array of bytes and stores them as Command and Data properties.
Does not need to save the checksum, as this class is only meant to represent a valid packet.
The above classes are sufficient to implement the receive protocol. You should be able to test it by mocking a SerialPort class (i.e., the ProtocolParser could actually take an IDataSource instead of a SerialPort).
You could then add a higher-level class to implement your device-specific functions, which would listen to the PacketReceived event of the ProtocolParser.
Of course it will better to use OOP design.
By what you explained, I'd make at least 2 classes:
Message
Executer
The message will receive the command from the device, and the Executer will handle the message.
The Message object will initiate with the device's answer. It will parse it, and hold fields as you described:
STX
COMMAND
DATA
CHKSUM
ETX
Then an Executer object will receive the Message object and do the actual execution of the message, and hold the logical code.
I would go a step further than Yochai's answer, and create the following classes:
Command: Actually not a class, but an Enum value so you can check against Command.Read, etc., rather than just "knowing" what 0x01 and 0x02 mean.
Message: Just a plain object (POJO/POCO/whatever) that's intended to hold a data representation of the message. This would contain the following fields:
Command (the enum type mentioned earlier)
Data: List of the data. Depending on how the data is represented, you might create a class for this, or you could just represent each datum as a string.
MessageParser: this would have a function that would parse a string or text stream and create a Message object. If the text is invalid, I'd throw a customized exception (another class), which can be caught by the caller.
MessageExecutor: This would take a Message object and perform the action that it represents.
By making the intermediate representation object (Message), you make it possible to separate the various actions you're performing. For example, if the Powers That Be decide that the message text can be sent as XML or JSON, you can create different MessageParser classes without having to mess with the logic that decides what to do with the message.
This also makes unit testing far easier, because you can test the message parser independently of the executor. First test the message parser by calling the parse function and examining the resulting Message object. Then test the executor by creating a Message object and ensuring that the appropriate action is taken.