EthCC 2: Rosco Kalis
Ethereum Paris·Wed, Oct 9, 2019, 12:00 AM
Speaker
EthCC 2 EthCC, the Ethereum Community Conference is created by the community, for the community. It brings together great minds and forethinkers, and allows the community to grow. Follow us : @AssethFR https://ethcc.io
Transcript
everyone welcome to this talk called using events unity smart contracts there's gonna be a bit of practical talk I'm gonna be discussing some techniques that you can use your own smart contracts development let me start by telling a little bit about myself so I'm a software engineer at encode which is a software consultancy firm in Amsterdam and were mainly doing work in the real estate industry and at encode I created the blockchain validated audit trail so that we could make sure that the data inside our applications could be trusted actually and that as part of my bachelor thesis last year at the University of Amsterdam right now so I'm also a graduate student at the University of Amsterdam I'm doing a master's in software engineering and I'm a huge open source advocate so almost everything we do it in code is all open source and we all we contribute to other open source projects and a lot of the projects I do on my own are also open source so last summer I did the Consensus developer program where I developed a decentralized sort of casino app where you can play roulette and maybe win some some aetherium back and I'm going to be using some of that code as some examples inside this inside this talk and so this talk is going to discuss the truffle assertions library as well which is a library that I created specifically to to help with the techniques that I'm going to be discussing so in this talk I'm going to be talking first about a little bit about what events are so how they are used and how they are used right now inside regular depth and then I will be talking about how events can be used in unit tests and maybe also what the complications can be when using these events in unit tests so what are events events are mainly a sort of log of smart contract usage so they they allow you to to to show what what's happening in your contract and in a way that it's not actually stored on the blockchain but it's stored in the logs of transaction and what that means that they are not accessible to two other contracts on the blockchain because they're not stored on the blockchain but they can be used very well as a way to communicate between your smart contracts and some of jillion application that you're running so these events they have some arguments that you can that you can use and they also have the option to have indexed arguments so that they can easily be searched for in your offline application so how are they used like I said it's mainly to log smart contracts functionality so you can sort of hook into to when your your transaction is is done you can see what it has performed it can be used as a sort of return value for these transactions because we can't we can't actually access the return values themselves from from these transactions and then it's possible to up for instance update the user interface with these returned values from the events and we used to be able to do that with that event that watcher event gets which has been updated to this sort of event emitter interface which which makes everything a bit a bit easier and bit more fluent which is been added in in web web 31.0 and as we can see in this example as well that we are we are able to filter only on the the events that are emitted for the for the current player so for the current account and we can use that to come to something like this which is a user interface that shows a list really of all the times someone or the player better than the app and what the outcome was and maybe if they were paid out so that's one of the one of the things that you can really use use these events for so on to testing whenever we're testing or smart contracts or when we're testing really any any software application it's good to to base these tests on the way they actual actually will be used so based on the actual application usage so if you're using these events as a way for instance to update your UI like I showed then you really do want to test that these that these events have been emitted or they have not been emitted or that the values are really correct and in this testing for a purpose or on basic based on application usage you can also sort of this can help you to decide whether you want to test with solidity or with JavaScript for instance if you're creating a library contract that should be used by other contracts on the blockchain then you probably want to be testing that using solidity because that's actually the application real world usage whereas if it's really only meant to be used for a vine off chain application like web 3 with 3 Jas for instance then you might get away with only testing it in JavaScript but it's always good to test it both ways because of course anyone can can interact in any way with the smart contract so onto these events in unit test so why are they not that widely used what what are the complications really to to to use these events so the first thing is that it's quite cumbersome to watch for these events inside your unit tests so you will probably end up doing something like like these guest first event things the the right one is the old the old way with truffle version 4 and web 3 version zero point is and the other is for the newer API so what you really want to do is just watch for an event and then once you get it you stop watching but what happens if the event doesn't emit for instance then you just keep on watching in your test and you keep on watching you keep on watching and your test doesn't continue it doesn't feel either so you just keep on waiting and your you don't also know what your other tests are going to do and at the same time truffle provides these transaction results with for instance a log of all the events and their arguments but these can be a bit difficult or bit clumsy at least you to par so you'll end up doing something like this get me the first log and the name and then check things with these arguments at the same time and you might also for instance if you go a step further you might create a filter function for your own for this log so you can really check out for instance you can filter all the play events and then check that there is at least one that's already a better way but the the best way is really to just not go through these logs manually and for that there's a few different libraries that can really help you with with parsing these transaction result logs more easily and the first one of these is a contract defense library which is which is pretty nice you don't really see the see the levels right now but it's so that allows you to to just easy more easily parse these transactions and get their arguments and get their their event logs more easily and this can also be used like in regular adapts if you if you want to be if you want to get these events more more easily and the second library is the one I created which is the travel services library and this really allows you to make some better assertions about whether a transact or whether a event has been emitted in transaction whether it has not been emitted and things like that so we want to look at making these assertions on these emitted events so with this library we can for instance check that an event has been emitted so we can do that by say okay we want to have the play event and you can add filter function on these arguments so we can say okay well the player must be the accounts that we use to bet and if we win then of course if we expect to win then the bet number must be equal to the winning number in this case and we can do some like computations in this function as well so it's really quite flexible as they're just like regular JavaScript filter functions and that means that you can make these these filter functions as fine-grained or a squirrel screen that you really want to do yourself so you can you can really decide that and at the same time you can also check that an event has not been emitted so for instance if we are playing our roulette game and the player has lost or we expect that it has lost and we we must know that it's it has not been limited that a payout event has not been emitted because they lost so when we can actually test for this event so we can test that I have been emitted or that they have not been emitted in these transactions then we can also kind of use these events to our advantage so we can place them at strategic points inside the inside the function so we can for instance like here we can check what the balance is before actually transferring money to the winner of a of a roulette game and when we do that we can really we can further specify our our test cases so usually you would for instance use your require statement if you if you always want a certain condition to be true when it's called but if you just want to test that a condition is true for a specific test case then you can really use this kind of construction to your advantage and the the final strategy that is it's a really strong strategy to to test callback functions so for instance if you're using oracle eyes or if you're using a different oracle service and they usually come with a callback so that it can reach your smart contract again after they have retrieved some data from from off the chain and of course if you're creating a depth then this dysfunction would automatically be called and then you would have your your back-end code somewhere set up to to handle that to handle this function call and probably update your UI in some way but since your tests are usually kind of like synchronous so your your tests execute in order you can't really expect expect this function somewhere later or expect the callback to be called so what we can do in this case is we can emit an event as well inside this callback function and by doing that we can then await the this event so using something like what we saw before like here we can we can get the first event and then get get the corresponding logs and a drawback of this is that it still it still comes with the same drawbacks that I discussed before so what if the event doesn't emit then you're kind of yeah the they don't really know then you keep on waiting again but there's not really a better way right now so this really at least allows you to test this callback function and otherwise you wouldn't even be able to test it at all so then you could retrieve this event and then with the with the data from this event the triple assertions library allows you to sort of recreate this truffle this truffle transaction result object so that it looks exactly the same as if as if the function we've been called directly and you would have just gotten back the transaction results so then we can see here for instance in the in the previous slide that we are actually using this callback transaction in the rest of our in the rest of our assertions so just to recap we've talked about events we've talked about how they are used we've talked about that testing should be based on actually real-world usage and next we discuss the Trappist versions library we discussed how it can be used to assert immediate events or not immediate events strategically placed events to to sort of test preconditions and we discussed testing of callback functions such as an Oracle callback um so that's what I want to leave it at and if you have any questions regarding these techniques or if you have any other ideas on how events might be used inside your own unit tests you thought about testing preconditions oh you're smart contracts yeah we defense but yeah vocals extra gas right to emit more events is that a drawback or a problem yeah that's that's definitely a drawback so with something that could be done as well is some other pattern that you can use this sort of overriding or overloading your functions in a special testing contract and then only add those at those events inside that inside that contract or you would have to sort of like manually get it out before deployment so yeah it's definitely not ideal in that in that way but it's yeah so okay thank you we got time for maybe one or two more all right thank you all for your attention [Applause]
Automatic transcript — names and jargon may be misspelled.