NEAR Live Contract Review | Episode 4: Fungible Tokens
Nothing is loaded from YouTube until you press play, and then without tracking cookies.
About this video
The 4th episode of our live contracts review series is about Fungible Tokens. Get insights and explanations directly from NEAR Core team members as they talk through the intricacies of important contracts on NEAR.
Follow the latest from NEAR Protocol on:
Website: nearprotocol.com Discord: near.ai/discord Medium: near.ai/medium Twitter: near.ai/twitter GitHub: near.ai/github
#WhiteboardSeries #Blockchain #FutureIsNEAR
Transcript
7,965 wordsCaptions as YouTube publishes them, usually machine-generated, so product and people names can be misheard.
- 0:01
hello everyone um this is another episode of live contract reviews and today we're gonna talk about tangible tokens and at this call we gonna discuss two standards so one is snap 21 which is very similar to ethereum your c20 standard and another one is a proposal for improvement that um removes some boilerplate that you need to do when you work with the fungible tokens so let me present um
- 0:48
okay so this is nomicon io this is where near has some specs and documentation and here we have a fungible token standard that was published it has version 2 oh but i think latest is for oh so the standard is not really updated so the standard fungible token interface is allows the following it allows you to create an account internally using this contract when you do some action it automatically creates
- 1:42
it has the following methods for calling it so it has transfer which is just the alias for transfer from which takes owner id as a predecessor then we have increase allowance and decrease allowance and it works similarly how ethereum your c20 standard works where you have um an account within a contract you have a balance which saying how many tokens you have and then you can set multiple allowances
- 2:24
which we call escrow account id so this is the contract which will be able to withdraw from your account some amount and when you increase allowance it allows this contract now to withdraw a certain amount more when they take it out the alarms automatically decreases and then you can decrease amount or decrease allowance to bring it back to zero all these methods are payable in order to pay for the storage
- 2:58
because a near protocol implements state staking so the idea here is every account that has a contract on it for example has to cover the storage of this account and contract and contract state and all the keys this these near tokens so for example if the current price is 10 kilobytes or 10 000 bytes for one year token and let's say you want to store 300 kilobytes it means you need to have
- 3:46
uh 30 year on this account if you're trying to add more bytes through some transaction but the account doesn't have it then doesn't have a balance to pay for the news date or to cover linear state then this transaction will fail it creates a lot of limitations on the contract development right now especially around contracts that are shared across multiple users this for because the gas is usually cheaper than the storage
- 4:24
so you can use you can create a transaction that increases the storage of the contract the state of the contract which requires you to cover with small balance and if you can do this indefinitely then you can spawn this contract is the fetch transaction until it exceeds the storage this allows you can essentially on one balance on one account just create very large amount of data on one account which will blow up the state of the
- 4:56
fungible token and eventually it will stop working and some logic gonna break that's why we introduced a payable which requires you to attach some balance that will cover the state increase when you modify the storage so let's say you modify the storage the state of the functional token by increasing the state by 400 bytes then from your attached balance you will have to pay this amount
- 5:37
um to the country yes that was a great explanation one question that i have had for a while about this is um is one kilobyte a thousand bytes or one thousand twenty it's a thousand bytes so it's around for humans not for machines so let's uh let's go to the implementation of the nft 21 um to basically go through this standard and see how it's done in the code so we have a structure for account
- 6:22
which has the following so this is slightly upgraded contract um i think it's version point four and it uses lookup maps instead of an order it map so the pricing per change is slightly lower we have a sub structure called account um it has balance it has lookup map which is an optimized version of an ordered map we don't that we don't need to iterate through them and then we have number of
- 7:01
allowances to to track whether we can delete this account or not uh when you create we take a full hash of 32 bytes and we create the lookup map from this hash so the prefix becomes unique because um nothing that here is 32 bytes then we send the lookup actually it's even more because the actual serialized is four extra bytes we have the following logic when you let's say issue increase allowance
- 7:50
then internal structure checks if there is its allowance is positive then we insert a new allowance and if it was not there before then we increase the number of allowances if it was there before we decrease the number of alliance this allows us to track number of unique escrow or unique allowances per account this will be important later question on the uh prefix why it seems like a very long
- 8:23
prefix don't we usually like to keep those prefixes small to save storage right good good question so we need this long prefix because this map is unique per account so it's this map will be different so it's a map within the map so this is not the main structure but it's a substructure of this map so we have lookup map for fungible token contract main structure so let's say you have a hash of chad dot near and this will be a prefix for
- 9:03
the your allowances map and then let's start making my own map and i will have a different prefix so our maps do not intersect with each other i'm really glad we got to this by the way um because this is a really good and very important thing i've seen partners who have kind of done this the wrong way and run into errors that are really hard to track down so just in terms of like
- 9:28
having collections within collections this is a good model to follow cool yeah so and this type of allowances um made this standard a little more complicated just because now like because every user or every account state is now not a constant size so when you add a new account to this to a token like let's say i transfer to you to say that this size of this is constant so i know if your account didn't exist and i added you now it's constant it's some amount of
- 10:08
bytes let's say 400 bytes but now you can increase this type of allowances multiple times and the size became non-constant for your account so it can grow so the second standard we'll discuss avoids this by having a constant state for um for a record constant size of the state anyway so the main structure fungible token has two fields one is a lookup map for account it takes a hash of the account as a key a prefix is a
- 10:56
so it's a short prefix and then um the value is um the account structure that we just saw now interesting uh in order to have any conflicts there now the size of the keys has to be different as well so let's say the prefix is a a small a and then we use a key which is just 32 bytes plus 4 bytes for the length of the case the longest prefix plus size of the key and another projects do not intersect the lengths of the keys are different will be fine without any like key conflicts
- 11:50
so this is a little more complicated than it should be but it's not yet improved again uh this is fairly standard insulation we take owner id and the total supply so owner id is the initial account that will receive full total supply within a fungible token and total supplies the number of tokens we mint there is no precision in this standard because precision is a metadata not really required to be part of the standard it's just a good to have
- 12:32
so we check that the state doesn't exist then we initialize itself so we initialize the map and the total supply but we don't return it yet we get a new account for the owner we give retire balance to this owner and we save this account to the state and only after this we return the object let's base look at the so there's two methods uh increase allowance and decrease allowance they're
- 13:13
very similar let's look at the increase of allowance it's called by predecessor so it's called by you you already should have some amount of tokens but not necessary increase allowance works the following way we check that the account is valid we get the predecessor we say you cannot add allowance to yourself we get your account we get um current allowance for the given escrow account for the given contract we increase this using saturating ads iterating add is
- 14:03
a rust helper that allows you to increase integer until it reaches the maximum limit without overflowing so for example for 32 bytes integer it will be something like 4 billion or 2 in 32 minus 1 and this way the allowance can be a maximum number without overflowing and we set it back using this then we save the account and finally we do refund storage so the way it works is the method is payable we originally
- 14:48
look at initial storage we call a host method saying what's my current storage usage it returns you the number of bytes your account occupies then once we did all the changes to to the state we call refund storage and we take the original amount we look at the current storage after all the changes in number of bytes we get the how many near tokens you attached then we do a refund amount
- 15:38
and doing it the following way if storage increased it means you're required to deposit this amount so we have a storage price per byte in year multiplied by the number of bytes and we say if you attached less let's revert everything you didn't attach enough tokens and it will revert all the changes you did during the call otherwise you you recalculate how much you are over attached so let's say you attached a thousand but you only
- 16:18
need 400 of bytes amount and then if you attached more we will refund it to you to the predecessor using the transfer and here if you decrease the storage amount so let's say you deleted an account to transfer all tokens then your account can be deleted we refund all tokens that you attached plus the amount of storage you released can is there a um issue to make storage price per byte something that you can get from end
- 17:05
since it could be adjusted in the future yeah we don't have this issue but it makes sense to to expose as well as expose all the fees so so maybe i'll provide the values from the config in some free format so this is how storage refund works and finally the way we do accounts is you hash the account id of the owner and you say give me this or a new account is a given cash and set account works somewhat similarly when you set a new account we basically check
- 17:52
if the account is non-default then we need to insert it back into the map if account was default which means balance is zero and allowances are zero we can basically delete it from the state because you don't really need it anymore so it kind of handles it implicitly which is a little strange and how you actually would write something like exchange standard let's say i want to
- 18:25
move tokens from one account to another now i need to think how many tokens i need to attach if the receiver exists or not if it doesn't exist then i need to attach tokens if the receiver existed then maybe i don't need to attach tokens but what happens if there was like my transaction front trend was front run to the receivers created so it's a lot of mess to write automated contract that uses fungible
- 18:57
token unless you can ask hey user give me enough near to cover for the storage for every transaction i don't care i'll just charge you extra maybe i'll do refund maybe i'm not gonna do refunds so the first standard that we currently use is a little challenging to implement um an exchange and the way exchange would work is you would basically increase the allowance in exchange by calling it token standard first and then you will call exchange through the another transaction so
- 19:39
exchange can call transfer from your account on your behalf similar how your c20 works you have transfer from you say uh who the owner who's new owner what's the amount it works the way it checks balances and then it checks who's calling this if i'm not the owner that means i need to have an allowance if allowance is not enough to transfer then it's a failure if not then we decrease
- 20:10
their loans then we save the account increase then create a new account and finally do a refund of storage so this how current old standard works and we also have a new standard that uh slightly improves on top of this so if there is no question on top of faults and there we can jump to the i think i have two questions um is the reason why we hash the account id to sort of obfuscate it from how it's
- 20:43
stored in state or is there another reason so one reason is we can standardize the size because hair should fix face while account id is variable size second it slightly preview pre prevents you from um creating the deep try where you can create something like uh a b a a b a a b and so on which will make it a little more expensive to access the final account so you can potentially make certain transactions more expensive
- 21:26
but also you know so there's two reasons okay um it's great and then my my final question is i think he might have been explaining this but i was thinking about something else um but in terms of decreasing allowance i say that that's payable but will that ever cost more to decrease allowance good question i think yeah it may not be so it probably doesn't need to be playable but um because yeah you can only decrease the
- 22:04
size of the account state so but we still need to do a refund if in case you actually set it to zero cool anything else all right so let me present back a window this is standard so the challenge with this was that it was pretty much just copied from ethereum rc 20 which has its own set of challenges such as biggest one you need two transactions to make use of a contract so let's say you go to unislope and you want to swap your token this unisof you first need to set an allowance towards unislope contract
- 22:57
and then you can you need to call the uniswap to do the actual spot so the second standard which called allowance-free save based token standards i'm going to explain the difference it addresses this issue by combining it into a single transaction the second challenge comes from near and our states taking the states taking is a problem because as i explained when you try to implement the unislope you need to know
- 23:42
about the state of the accounts and you can cannot make expectation how much deposits you need to do for transfers so so this addresses two of them and the third one is some kind of weird allowance abuse where you can most contracts will ask you to give unlimited allowance first and when you do this they means they can spend all your tokens not just the amount you want for the given slot um the way
- 24:23
this pro wait say that it works so so let's say you go to unislope on ethereum and first thing you approve the uni swap by giving allowance so if you don't know how much you want to swap that they will usually ask like give me all the like unlimited on the allowance like microsoft i think a lot of the contracts do this because they don't want to like bug you twice got it okay it'll cost like 60 70 cents each time or something too just for those approvals
- 25:05
right okay yeah this uh this is something that we're that i'm dealing with with the rainbow bridge as well and it may it's it's only allowing 10 tokens if you're transferring 10 tokens to ethereum and then transferring those it doesn't just like say all right give me access to all of your die forever that seems really bad so when you know the exact size this is cool for unislow well you need to approve
- 25:33
slightly more for slippage right so so it's a rational for this we remove extra space that's required to store allowance because there's no allowances anymore these instead of like permanent allowance you switch it to temporary allowance when you issue a transaction it essentially gives the loans to the receiver instead of having to give it forever so it removes the extra transaction required to set allowance because it's
- 26:12
done in one transaction it slightly simplifies the usage of the contract because it's a single call it allows to be chain transaction which is very relevant to us so it enables some type of composibility for the standard and we somewhat remove payable not really it's gonna be slightly different how do you handle it so it's not really true but it helps the way it works is you have two types of transfers
- 26:51
the first transfer called transfer unsafe it's basically just a regular transfer you grab the receiver id and the amount and we just take your tokens and put it on the receiver's account that's it so that's why it's unsafe because you cannot transfer to a contract it will just grab it from you so it doesn't have any logic on the receiver second is transfer to be safe and this is um the way that
- 27:26
most contract transfers can handle this it takes uh three arguments receiver is the contract on which you you call in so in this case let's uh look at the accounts alice is the owner of the token then let's call it die as a funchable token contract and unislop is a junior swap contract that will handle a swap of die to near the way you do this receiver gonna be unislope signer and predecessors are
- 28:11
alice and current account id is dying so this is token standard on die uh you have amount this is the maximum amount of tokens that can be withdrawn from your account not exact amount but the maximum and we will lock all these tokens out of your balance for the duration of the transaction and finally a payload this is a string that can be anything that is a json string so you can encode some base64 data into
- 28:54
this payload and it returns a promise so it doesn't return you a value immediately instead internally what it does it withdraws the amount from your balance and put it into a temporary structure that we call a safe so that's stored locally in this contract for the duration of the transaction the save contains the following it has sender id doesn't have it it has the amount and the receiver so the amount of tokens
- 29:34
that are remaining in the save so this is what we take so example can be i want to swap 500 day to near i let's say call the transaction and say amount 500 so save will be created where amount is 500 and a receiver is unislow so then we store the safe into the storage persistent storage of the die contract then we call receiver id so the remote contract it is the method on tokenreceive which gives the
- 30:16
following that gives the sender id this is the predecessor in this case it's alice it gives the amount 500 and gives the safe id it's just some unique number u64 from which unisop can withdraw it so we call unislope on token receive and payload payload can be something explaining what type of swap you want to do so front end can create this payload and then pass it to this method what happens on unislope is
- 30:59
they get called on token receive now they know who called them because they have predecessors so they can verify that i called them they know who sent how much and why this is payload payload is why they send it like what exactly this action is so payload can explain i want to swap 500 near towards oh 500 diet towards like five year and now unisop it essentially blocks this transaction until completion or
- 31:37
and finally what this method does it attaches the callback on itself called resolve save it gives saves id and sender id so the way this works you call transfers with safe it calls on token receipt from unislope and once this completes it will call resolve safe back on itself so now union swap visiting its call can call withdraw from safe back on day to transfer the amount from the temporary safe to to a different receiver so it can
- 32:21
transfer to itself or let's say to bob or someone else and they can specify amount how much they want to transfer from the given save so let's say because of slippage they only need to transfer 480 tokens um then they can just call this draw from say give the safe id that was passed to them receiver id gonna be unislope and amount gonna be 480.
- 32:56
when this is called uh internally we will do the deposit to the receiver account but the internal safe amount will get decreased from 500 to 20. because only 20 remains in the save and it can verify that the safe id is owned by the predecessor so only predecessor can act on the safe if there is two calls in parallel because of async the saves are not mixed let's say alice called unison twice while this transaction is
- 33:32
still flying the two saves are not gonna mix so they are not gonna withdraw from the same balance twice the balances of alice is not going to mix because you will withdraw from alice twice in two different states so it stays uh so it guards against the re-entrance essentially and like prevents different balance issues um so union swap when they call this they should not end their promise so they should not call it in parallel instead they should depend on the result of this this is important so the resolve save is
- 34:15
not called yet when unison finishes the operation on the save like this draw and complete it they just ends their call and this resolve safe is being called on the die die grabs the safe idc that only 20 tokens left it puts it back to the sender and returns the amount left saying like okay only like for example or like it can return how much left i i don't remember the standard is a little maybe a little not updated
- 35:03
and finally receive inside this explains here so this is the proposal and let me know if you have questions for the proposal we can jump to implementation of this proposal to explain a little more logic behind the promises maybe it will be more clear these some examples okay yeah i i think i get this i think this would be a really fun diagram to have in just a simple alice bob walk through uh i i guess i still don't
- 35:45
exactly understand like the so uniswap calls the withdrawal and then yeah automatically the promise will call the um what's called the final callback your result that's the one yeah so so the reason for this as well is let's say a unislope does not implement a proper api then it basically just going to return you token so they are not going to be locked on unislope because the prompt is going to fail immediately or it can panic at any point for example you didn't attach enough gas
- 36:30
or some other stuff in this case the safe will immediately be reverted back to the origin amount um there is more slightly more complicated stuff around gas than stuff because it's um a bit more explicit here so we say for basic compute we need five tera gas for creating a promising need five tera gas for data dependency we need temperatures uh so the minimum amount that i need to pass the receiver
- 37:05
is gas for promise plus base compute because it can just do this draw from safe and return it the the amount of gas for the resolve safe is just a base compute and it just computes how much gas i need because it passes all the remaining gas to unislope so also the implementation is slightly more interesting than regular map it does more optimizations um first it introduces a short account
- 37:49
hash it's similar how ethereum cuts your public key from 32 bytes to 20 bytes assuming there is enough entropy so they don't collide similar we can do the same here it's a fixed size so we stay four bytes on this at the same time the except this one gets the first 20 bytes of hash instead of a last um account id now similarly to net 21 it's just a simple balance it's just 16 bytes
- 38:31
fixed size pretty good save this is the structure that was described in the proposal it only have hash of the receiver id and the balance remaining in the save to optimize on the size of the save and finally the standard oh the domain structure has a map of accounts from short account cash which is 20 bytes to the account which is 16 bytes and this map is essentially every entry is only 77 bytes
- 39:20
which is a very small amount of near if you burn something like 300 terror gas of gas it's enough to pay for the storage through 30 refunds on account but we don't burn it here so they're still explicit account payments second the temporary structure for saves saves only leave while the transactions are active so we do not separately pay for the saves next safe id is just a u64 and total supply there is a structure to tell
- 40:07
how much total supply is this is the api high level api for calling a receiver in this case a unislop for example in the example this is a callback on ourself and implementation it will it's somewhat similar it uses some magic using rust so we don't explicitly call hash on the ownership so sref converts a valid account id to reference to account id and then we have a from implementation on ros that converts it to a structured
- 41:11
short hashing account hash which hashes the account and creates this so this stuff essentially casts account id into a short hash by hashing it and truncating it this into and then we give the full total supply to them how does the azref get there i missed that as ref is from a valid account id it returns you accounted by reference i see thank you and then from reference account id you can cost it cast it to um too short accountability
- 42:00
anyway so we initialize the structure and give full token transfer and save implementation uses two helper methods withdraw from sender and deposit to account and it um this raw from standard it uses predecessor account id but it needs a receiver for safety checks so it's saying you cannot transfer to yourself uh you cannot transfer to the stock and standard another safety check
- 42:44
and then it basically takes the balance out and deposit to account is um deposits to account that you pass so in this case a receiver and the more interesting is transfer of safe the way it works is we basically first calculate how much gas you need to pass the receiver and if it's not enough then we panic immediately so you don't try to do any logic you take the amount from the sender
- 43:33
again using this magic helper so sender is alice we take the amount from alice we create a new save by using next safe id enter in increase the increment of the save we so we put that amount into the save and save this save save the save into the internal structure now we create a promise to in this case in the example was uni swap and then a callback back to die on the promise to unisoft we give all the remaining gas like some large
- 44:26
piece of remaining gas to unislope so they can complete operation and maybe do a bunch of chain operations so you can attach if you attach 3000 or 300 tara gas majority of this gas will land on unisop so they can do some more complicated calls if they needed to we pass this data payload is just a string so just pass through this and then we do a call back on ourselves and so so in terms of the passing on extra gas to uniswap
- 45:11
that would be on them when they are calling this contract on your behalf to pass in enough like the minimum gas that you can pass is actually wouldn't be enough for something like that right yeah so uniform basically panic for example but let's say you need a lot of gas on your side you just you can just panic immediately and it will be okay because i can see receiver there is the that's an argument that was
- 45:42
passed in so this is another cost function that's saying how much gas was attached to this particular function call and then we say how much we need i see so you would do the same thing on the unit swap side with like oh i didn't get enough yet so this first the safe would be created but the promise call to uniswap would fail because not enough gas is passed on so let's quickly go through this
- 46:16
contract i don't think there is a lot of stuff remaining here and then maybe go to unislope to explain this particular receiving part so withdraw from safe is that called from unisoft to us you basically grab the safe out of the structure saying like okay say it doesn't exist well that's a problem uh we verify the predecessor matches the hash if the save withdrawal is called not
- 46:50
that by the safe owner then you cannot do this so you cannot take someone else safe then we just take this money out of this amount out of the safe and put the save back and we deposit to this account again i haven't talked about storage taken yet and i'll explain how it works here finally when the callback is getting called on resolve safe we take the safe out again safe should exist because it's from us
- 47:31
and if save positive balance is still positive it means we need to put put this balance back to the account if account doesn't exist for some reason like you deleted it while the safe was in flight then we just say these tokens were burnt so there is not much we could have done so safe was lost on the way if account did exist then we return this money back to the account finally the way we handle storage taking in this account we introduced two
- 48:16
calls called register account and unregister account register account works somewhat similarly to refunding originally you call it you pay 77 bytes enough of near and we create this account for you so if account already exists it's already exist nothing to worry about if account didn't exist then we basically put the new account in calculate the difference refund the remaining difference and unregister an account right now expect your account to be empty but
- 49:01
imagine you should leave this limitation too if the account balance is positive it fails if not then it doesn't then it deletes this account here and refunds you the difference so instead of being on every call of transfer increase allowance decreasing out this is handled through these two methods separately a front-end can handle it so first time you want to use a unislope a token it will register your account and you will pay bytes
- 49:57
this is really really interesting i've got a couple of questions if we have time or people want to go over a little bit wait for um a bit this is what this is uh this is super interesting have you guys ever heard of this before i've heard of it i haven't dug in this is great um i don't know why we still have an ep 21 it seems like we should just use this everywhere it seems superior in
- 50:27
like every way yeah so okay i'm back um so basically yeah so this can be a standard on its own because this is a common pattern that will be used for example on unislope as well because on unislope in order to provide the liquidity to a pool well you need to register your account on unisop and pay for the like state staking on this type so something like registering an account and a registering account and potentially like having forced argument which saying burn
- 51:08
all my tokens i don't care but give me back my storage is a good standard and finally it has account exist method that just verifies if account exist or not so we almost out of time i don't know if you guys have a few more minutes but i want to go to unislope to demonstrate how onreceive this save works we are not going to discuss entire unit slope first just this particular callback
- 51:46
so unislope knows which this is um a single pool which works one fungible token and native near token it verifies that it was called by the fungible token that it's working with if not then it's saying no then it gets this payload from as you saw payload was a string we use base64 vacu8 which is expect the string to be in basically for format and it will cause nearby engine will convert it back to a vector u8 and we just parse it using a borscht on
- 52:33
serialize so this uniform can work with two different calls deposit and swap one year so same input on receiving tokens can have two different logical paths based on the payload but other implementation can do this differently so it's not limited by the standard it gets the amount and based on the payload it does two different actions deposit is somewhat similar it basically makes sure that the account exists
- 53:13
and it calls hey okay uh please draw from save and deposit and once you withdraw from save call me back so unisop has a callback on top of this as you can see it doesn't check any gas or like similarly oh do i have enough gas to complete all of this because if any of this fails is not enough gas entire thing going to fail in panic and it will go back to the token standard and return all the tokens it knows how much gas it has to attach
- 53:54
for this draw from save because the standard said it's five tier i guess is enough and finally it um basically what it does it takes the save deposits it to itself but once it's finished credits this amount to the owner of this so once the that succeeded this failed it shouldn't but if possible for some reason it just credits the account of the owner and on swap is slightly more interesting because
- 54:39
um it knows extra data through the payloads it knows how much near you want for your swap and then it you don't need to have an account on uni swap to do the swap so you don't need to do two separate transaction basically you only need to have tokens then you can go to unislope issue one transaction to swap your tokens um to near it will call you will call as alice you will call die that i will call unislap unisop will
- 55:18
withdraw from your balance and give you near so it knows how many how many tokens you need to grab from the pool or the in here for the desired amount you can get and instead of taking all of your tokens that you attached it will only take the required token amount and then it calls okay let's uh withdraw from the safe so it doesn't even check the success of this it believes that the standard that implements the token standard cannot
- 55:59
fail at any point so it's just trust that once i get the money the required amount because it verified this through input go send desired mirror amount back to this swapper and essentially that just allows you to do through a single transaction a swap without approval so obviously unislop not gonna authorize your access key to the token sender instead it will just call a wallet to sign this transaction
- 56:42
uh so this is how the receiving side works and now when union swap wants to do reverse this is for example swap for tokens so you pay near and you want to receive tokens it verifies all your balance calculates and then it creates a promise to say okay i want to grab your tokens oh it's saying i want to transfer from my unison balance because it knows the balance on the to to your account and then it doesn't refund for a reason
- 57:38
if you don't have an account but maybe it's a bad idea because it creates an option so that's um how that standard works that's what it should yeah um are there a couple minutes you guys are willing to yeah clap clap clap for sure are you guys down to spend a couple minutes in q a or is everyone antsy no i'm ready to um one of my first thoughts was um as chad's question was about like why have any p21 and
- 58:10
i think that like from kind of like a business point of view and all that people have been using erc20 for so long that it makes a lot and it's been so battle tested that it makes it it did and probably still does make sense to kind of copy that for a little bit while we introduce these like better ideas you know it's just so simple um i feel like this will take some like proving to the community um like how awesome it is uh one like
- 58:36
really like high level thought that i had is like uh like it was slightly confusing when i was first reading about safes because it's actually like the word vault kind of makes more sense because we have like ones that unsafe and so then you think like security safety but then as i said a safe like a bank vault um so just like wording wise it's like a just small small like idea there um
- 58:59
secondly like i remember when i was reading mastering ethereum the book i was like i read this like five times like i was so confused when they like cut the length of the public key down for the address and i was like why why would you lose the the entropy um so like i understand it's really like entropic but like i never really understood that and i don't really know if we want to like emulate that but
- 59:25
that's just like my opinion i think from safety perspective 20 bytes seems um it should be enough at the same time um if you know this uh problem of like vision one like how many students you need that they have a more than 50 chance of having birthday in the same day and it seems like a square of or square root of the number of days in a year and so square root of this is 10 bytes it means you need about to generate about
- 1:00:13
10 bytes of shutter 56 keys in order to find the collision but this is still pretty large number it means it's a 20 10 and 20 about the same size so if i'm not mistaken because it's like 256 in power of 10 which is still kind of looks like a number that cannot be achieved because you need to store all of them in memory in order to to find the collision so a rainbow table cannot solve it for you
- 1:01:04
so it seems like it's safe we can go for like 24 bytes if you see like an extra need at the same time by the moment the check capabilities arrive there we probably can upgrade it i guess i'm curious like if if this is all the entropy that's needed then why are public keys why was the length chosen for public keys that was chosen right like i would assume that public keys were given this length because the chances of them colliding is so
- 1:01:39
infinitesimal that it was deemed safe so cutting them down to 20 bites or whatever like removes some of that guarantee um so that's why it feels a little bit weird like well power of two so 16 is not enough because 16 is probably very realistic to achieve in like 5-10 years but yeah for public keys the next power of two was 32 bytes kinda the future is near i actually don't know i don't know why it was picked uh probably like some logic around mass that it makes it easier to compute
- 1:02:26
for some reason um going back to the like any p21 versus just having everyone use this to me it seems like if any p21 comes into common use which at this point like the people building on here are using it then it kind of hamstrings the effort to have people use this instead doesn't it like i think this if we want to push this as a standard it behooves us to push it right from the beginning so that a lot more projects
- 1:03:02
like the the number of projects using it increases the utility by you know like that's where it becomes really powerful versus there's a mix of this and any p21 that's more painful for everyone i feel like nap 21 will not be able to do some operations on the kidney slope without force depositing to unisoft so it means three transactions for a swap so you first will probably grab a loans
- 1:03:35
then transfer to unislope and then you will be able to swap so that seems like one year it doesn't matter it's like well on unislope you can have this a lot like a key so you can get it uh one more thing i was thinking about on the standard which is slightly weird and that the i'm thinking whether it makes sense to require a deposit on every single of these two and the deposit is one yocton year so i want to make it prevent people from calling
- 1:04:19
this function without confirming its reward so access keys on year works only if there's zero deposit if this method requires you to deposit at least one yacht a year it means you cannot call this method through a function called access key so if i get my access key log into the diet contract then i will not be able to transfer it without getting gotten going through wallet it's a little like ridiculous stuff but it makes some interesting idea because it essentially prevents you from being
- 1:04:59
able to transfer without explicit action at the same time that's a good idea some um methods probably can wrap it up internally they can introduce like actual transfer wrapper on but the standards like just the token itself maybe it doesn't this also leads me to something that's totally off topic but like for a future video perhaps like how can one prove that they're using a standard like i know when you use like etherscan you can sometimes even see the code
- 1:05:41
um that would be quite interesting because we are assuming that people are actually compiling this um but i i i know it can be done but i don't really know how to prove that the contract that was deployed is the contract they say was deployed so we can't prove the exact code but we cannot prove the standard so let's say you have some slightly custom implementation if you provide this code then you can
- 1:06:06
we can essentially recompile and build it using a docker build that produces very predictable binary so it's the same binary no matter who compiles the code and that's the way you can you compare that to the what key to funding account to the cash yeah to the cash of the code so you hash this binary and if the hash of the code matches the hash that you receive then you can link it to the source code
- 1:06:38
currently we thought about like putting a json file into the core repo so doing this currently through a manual way where we just link all core contracts to their github hash on which they will deployed and this way we can in short term show this data into explorer but longer term it seems like there should be some repo that can do reproducible builds automatically you submit some standard github repo and it
- 1:07:18
produces it and links it and people somewhat trust it um so that's the way all right i i think we weigh over time this time and but this was a pretty good session i hope yeah you listeners learned a lot more on fungible tokens including promises and the way we think about how they can be composed in near async environment and i hope the new standard get more adaption thanks bye