My question relates to the minting process to create an NTF.
I might be wrong but the tokenization function can be compared to an hashing function which
takes as input the media
and
outputs the token.
Yeah this actually already is a question, cause otherwise the main question maybe does not makes sense.
Assuming the comparison to an hash function makes sense and forgetting about collisions let's assume the following scenario:
I create a digital artwork and the related NFT. It's published and sells somehow (hopefully :D).
Imagine Mr.XYZW is a well known digital artist who gets huge revenues from NFT, he sees my artwork, somehow he likes it but
also thinks the artwork would look better if for example the colors simply get inverted. Here I'm just mentioning one of all
the possible changes he could do, the point is that easily those changes could not even be noticeable to the human eye, but not to the tokenizer,
which would in the end clearly create a different token.
Now the problem should be clear.
If what I said makes sense, how is it usually tackled?
in case it doesn’t, please help me to understand.
Thank you
tokenization function can be compared to an hashing function which takes as input the media and outputs the token
This is an incorrect assumption.
You can compare an NFT collection (at least per the most widely used standard - ERC-721) to a key-value dictionary, where the key is an integer ID, and the value is a URL. The standard defines that the URL should lead to a JSON containing the token name, description, and image URL.
But there's no hashing function that would calculate the token parameters based on the image.
Each collection (holding several NFTs) is a smart contract deployed on a different address (e.g. 0x12345). Also, each NFT within its collection has a unique ID (e.g. 1).
Combination of the collection address and the token ID can be used as a unique identificator of each NFT (e.g. 0x12345 / 1).
It's technically possible for multiple different NFTs (no matter whether they're in the same or different collections) to lead to very similar images or even the same image. But the combination of collection address and token ID is always unique.
How many pairs of key/value can I store in a mapping using Solidity?
mapping(bytes32 => bytes32) pair
If this isn't efficient to store one pair key/value every second or so, can you suggest a better way? I thought of using Swarm/IPFS but I need to lean the design the maximum...
The solidity docs say “Mappings can be seen as hash tables which are virtually initialized such that every possible key exists and is mapped to a value whose byte-representation is all zeros” - there is no theoretical limit to the size of a mapping in solidity.
If you need to make a call to your contract every second to put something in your mapping, your bottleneck will not be in how the mapping type itself works (for which one second is plenty to put a new key-value pair in the mapping), but more so in Ethereum itself, as the network currently only supports around 15 transactions per second, so to have your contract call be included in those 15 every second will be very difficult, even with an exorbitant gas price.
I am trying to write a program in object-oriented style. I have some confusions when coding the interaction between two objects.
Scenario:
Person (John) gives Person (Betty) $ 5.
Possible solutions (pseudo code):
A) John.pays(Betty, 5);
B) Betty.receives(John, 5);
C) Bank.transfer(John, Betty, 5);
D)
begin transaction:
John.decrease(5);
Betty.increase(5);
end transaction:
E) Service.transferMoney(John, Betty, 5); // Service is a generic service object
Please tell me which one is a more appropriate way of coding in OOP way, and the reason behind it. I am looking for some guidelines like "Tell, Don't Ask" rule.
Thanks.
One thing I've noticed is that people that are new to OOP get caught up in trying to map the physical world into the code they are writing. Do you really care that John and Betty are people or are you actually wanting to depict a bank account? I think your choice of objects in the example actually make it harder to figure out the solution to the problem.
The important parts of this are
1) Where to put the logic of how to move the money.
2) Where to store the data of how much money each person has.
You need to decide if you want to talk about the problem in the context of a person or a customer of a bank (may be a person, company, or something else). I'm guessing you are talking about a customer because assuming it is a person would be limiting and misleading. Also, a Bank is a pretty generic term, is it the big brick building with people inside of it or is it the online website with several different pages that do different things.
A bank account object can have a method (possibly static depending on how you decide to store your data and what all you are going to use your object for) that knows how to transfer from one account to another. The logic of how to transfer does not belong to Betty or John or a bank, it belongs to a bankAccount which can have special logic based on the type of account if there are fee's involved or the like. If you gave that logic to the bank you would end up with a giant bank class with methods for everything from greating a customer to dealing with money in very specific account types. Each account type my have different rules for how it handles transfers. Think of times where you may want to show a transfer or deposit as pending.
If you are just solving the problem of transfering money, there is no need to create a bunch of objects. Based on the known requirements and presumed future requirements the below would be a good choice.
CheckingAccount.Transfer(johnsAccountNo, bettysAccountNo, amount)
Can I ask a question now? Who controls the money? Does John decide the transaction amount, does Betty, or some unspecified 3rd party?
The reason I am asking is because there is no real right or wrong answer here, just one that might be more flexible, or robust than the others. If this is a real life situation then I would model the transaction as something that both parties have to agree on before it proceeds, and the person spending the money (John) initiating it. Something like answer C and #Mysterie Man
tx transaction_request = John.WantsToBuyFor(5); //check if John can
if( Betty.AgreesWith( transaction_request ) ) //check if Betty wants
{
transaction_request.FinalizeWith(Betty); //Do it with Betty
}
and the FinalizeWith function does the math
void FinalizeWith(Person party)
{
requestor.cash -= amount;
party.cash += amount;
{
Of course you might want to add some description of what item is John buying.
The answer to this question is a long and complicated one that you'll get in bits and pieces from a large number of people. Why only in bits and pieces? Because the correct answer depends almost entirely upon what your system's requirements are.
One trap you will have to make sure you don't fall into, however, is this one. Read the answers you get here. You'll get a lot of good advice. (Pay the most attention to the advice that's been voted up a lot.) Once you've read and understood those, read Steve Yegge's rant (and understand it!) as well. It will save you sanity in the long run.
I'd vote for none of the above :)
Why is John paying Betty? That's an important question, as it explains where the entry point is. Let's say John owes Betty money, and it's payday.
public class John
{
public void onPayday()
{
Betty.Receive(5.0f);
}
}
This is if you want to go with a pure object-interaction style approach, of course.
The difference here is that we don't have an outside routine coordinating the interactions between John and Betty. Instead, we have John responding to external events, and choosing when to interact with Betty. This style also leads to very easy descriptions of desired functionality - eg "on payday, John should pay Betty."
This is a pretty good example of what Inversion of Control means - the objects are interacting with each other, rather than being manipulated by some external routine. It's also an exmaple of Tell, Don't Ask, as the objects are telling each other things (John was told it's payday, John tells Betty to accept 5 dollars).
There are a number of alternate solutions here. For instance,
Betty.Receieves(John.Gives(5))
This assumes that the Gives function returns the amount given.
tx = CashTransaction(John, Betty);
tx.Transfer(5);
This assumes the first prameter is the Payor, and the second is the Payee, then you can perform multiple transactions without creating new objects.
Things can be modeled in a number of ways. You should choose the one that most closely resembles what you are trying to model.
There is one property of pure OOP that can help with the example which easily passes under the radar, but the object-capability model makes explicit and centers on. The linked document ("From Objects to Capabilities" (FOtC)) goes into the topic in detail, but (in short) the point of capabilities is that the ability of an object to affect its world is limited to objects it has references to. That may not seem significant at first, but is very important when it comes to protecting access and affects what methods of a class are available in methods of other classes.
Option A) gives account John access to account Betty, while option B) gives Betty access to account John; neither is desirable. With option C), account access is mediated by a Bank, so only Banks could steal or counterfeit money. Option D) is different than the other three: the others show a message being sent but not the implementation, while D) is a method implementation that doesn't show what message it handles, nor what class it handles it for. D) could easily be the implementation for any of the first three options.
FOtC has the beginning of a solution that includes a few other classes:
sealers & unsealers,
purses, which are a little like accounts in that they contain money but don't necessarily have an owner.
mints, which are the only things that can create purses with positive balances
A mint has a sealer/unsealer pair, which it endows to a purse whenever the mint creates one. Purses oversee balance changes; they use the sealer when decreasing a balance, and the unsealer to transfer from one purse to another. Purses can spawn empty purses. Because of the use of sealers & unsealers, a purse only works with other purses created by the same mint. Someone can't write their own purse to counterfeit money; only an object with access to a mint can create money. Counterfeiting is prevented by limiting access to mints.
Anyone with access to a purse can initiate a transaction by spawning an empty purse and transferring money from the first purse into it. The temporary purse can then be sent to a recipient, which can transfer money from the temporary purse to some other purse that it owns. Theft is prevented by limiting access to purses. For example, a bank holds purses on behalf of clients in accounts. Since a bank has access only to the purses of its clients' accounts and temporary purses, only a client's bank can steal from the client (though note that in a transfer between bank accounts, there are two clients that can be victimized, hence two potential thieves).
This system is missing some important details, such as monetary authorities (which hold references to one or more mints) to create money.
All in all, monetary transactions are tricky to implement securely, and thus may not be the best examples to learn the basics of OOP.
If you really want to get OOPy, try the following
Person Betty,John;
CashTransfer PocketMoney;
PocketMoney.from = John;
PocketMoney.to = Betty;
PocketMoney.amount = 20.00;
PocketMoney.transfer();
The point of OOP isn't to make code more like written language, but to have objects with different methods and parameters to make code more readable.
So from the above code, you can see that John is giving Betty $20 in pocket money. The code is meaningful, allowing for easier code readability, as well as understandability.
My vote: C. Where C does what D does (e.g. doesn't lose money, etc.).
In this small example, "the bank" is a perfectly valid entity which knows how much money John and Betty have. Neither John nor Betty should be able to lie to the bank.
Don't be afraid to invert (or not) the logic in an "OO" program as required for the situation.
You should model according to your domain. Option C looks best choice as it will separate the transaction logic into the Bank\Service class.
This is a question I often struggle with myself as a novice programmer. I agree that "C" seems like the best choice. In something like this, I think it's best to use a "neutral" entity such as the "bank". This actually models most real life transactions of importance since most transactions of import utilize checks and/or credit (a neutral 3rd party).
Being new to OOP and finally using some OOP, I'd say that it should be A and B.
We are focusing on persons and it's up to each person to handle his money. We don't know if he's going to use the bank or if he's just getting cash directly from Betty.
You created a Person class and you add methods to the class with two methods: send and recieve. It also must have a public var named balance to keep track of their balances.
You create two Person objects: Betty and John. Use methods accordingly. Like John.sends(Betty, 5). That should create Betty and update Betty's balance as well.
What if they want to use the bank? Add another method, say... Transfer(acct) whatever it is.
That's what I would think.
I'm refactoring a website I build. It's a website for a travel agency. I'm thinking of implementing the repository pattern.
The travel agency has two divisions, that have their own website and target different groups of customers. The backend however is the same for both websites. They both access the same DB tables. Some tables simply have columns that identify what division the records are for.
Let's imagine I want to build a TripRepository, that will be able to return Trip objects. Do you feel it makes sense to create a Repository that takes the Division as a constructor argument? Such that all results will be only for that Division?
So in other words, in pseudo code:
class TripRepository
{
method constructor( Devision );
// this will then only return Trips for the Devision passed to the constructor
method findAllTrips( /* some other criteria */ );
}
I could very well have it as an optional constructor argument of course, and even have a setter to switch Devisions if need be... but in general is there something objectional with doing this?
Or should I just always pass the Devision criterium to all search methods?
Unless your findAllTrips(...) method has completely different logic based on the "Devision" (shouldn't it be Division, btw?) there is no reason to create seperate instances. And even if you do for some reason, I suppose you will have to put the instantiated objects in some other collection, where they will be accessed using... Devision as a key (i.e. parameter).
So personally I think it wouldn't be a good design decision: doesn't look intuitive and whoever meet this in your code in the future will probably wonder what the real motive was to go this route.
GUIDs are typically used for uniquely identifying all kinds of entities - requests from external systems, files, whatever. Work like magic - you call a "GiveMeGuid()" (UuidCreate() on Windows) function - and a fresh new GUID is here at your service.
Given my code really calls that "GiveMeGuid()" function each time I need a new GUID is there any not so obvious way to misuse it?
Just found an answer to an old question: How deterministic Are .Net GUIDs?. Requoting it:
It's not a complete answer, but I can tell you that the 13th hex digit is always 4 because it denotes the version of the algorithm used to generate the GUID (id est, v4); also, and I quote Wikipedia:
Cryptanalysis of the WinAPI GUID generator shows that, since the sequence of V4 GUIDs is pseudo-random, given the initial state one can predict up to the next 250 000 GUIDs returned by the function UuidCreate. This is why GUIDs should not be used in cryptography, e.g., as random keys.
So, if you got lucky and get same seed, you'll break 250k mirrors in sequence. To quote another Wikipedia piece:
While each generated GUID is not guaranteed to be unique, the total number of unique keys (2128 or 3.4×1038) is so large that the probability of the same number being generated twice is extremely small.
Bottom line: maybe a misuse form it's to consider GUID always unique.
It depends. Some implementations of GUID generation are time dependant, so calling CreateGuid in quick succession MAY create clashing GUIDs.
edit: I now remember the problem. I was once working on some php code where the GUID generating function was reseeding the RNG with the system time each call. Don't do this.
The only way I can see of misusing a Guid is trying to interpret the value in some logical manner. Not that it really invites you to do so, which is one of the characteristics around Guid's that I really like.
Some GUIDs include some identifier of the machine it was generated on, so it can be used in client/server environments, but some can't. Be sure if yours doesn't to not use them in, for instance, a database multiple clients access.
Maybe the entropy could be manipulated by playing with some parameters used to generate the GUIDs in the first place (e.g. interface identifiers).