Interacting with Smart Contracts in Streams

EDCON 2019 · 13 Apr 2019 · 14:46

Adrian Li presents Drizzle Utils, an RxJS-based library for observing smart contracts. A counter example shows streams for method calls, events and decoded contract state, followed by a small React demonstration. He also explains provider handling and utilities for tracking new blocks and MetaMask account changes, so interfaces can update as blockchain state changes.

Speakers

Topics

From EDCON 2019, hosted by EDCON.

Transcript

last but not least let's welcome Adrian Lee who is the lead front-end developer at truffles and you'll be talking about live streaming your SMAC contracts all right thanks guys thanks to all the organizers for leaving the best presentation for last it's good to kind of wrap it up so thanks to the sound guy AV and all that and all the clapping it's totally not set up beforehand okay so today I'm gonna talk about live streaming your smart contract so let's get started

start with the quote this is a quote by Brett Victor someone who puts a lot of time into understanding what makes programming easy enjoyable you know learn about programming as you can see in a link there I'm just gonna read it out people understand what they can see if a programmer cannot see what a programmer program is doing she can't understand it so it's all about providing visibility to what's actually happening as you're making your your DAP right because a lot of times things are happening on chain and you don't even know you know what's the state of your contract like what events are being fired these are all questions that are really hard if all you did was like a truffle in it or maybe some other framework you know you have no idea what's going on until you you know and

I'm coming from a very front-end perspective obviously so you know it's all about this talk is all about seeing the smart contract state so less about you know making mutations and rights but more about like trying to read and understand what's going on so these are some of the things that well I particularly want to see and I think things we want to see when we're making something right we want to be able to read constant method calls so these are things like getter functions in your smart contracts all right it could be like getting the balances you know whatever accounts you have on that smart contract second thing would be like contract events you know everyone wants watch events I mean that's kind of what they're for right and finally just the whole contract state in general right

like what is on the contract itself right let's see if we can do something about that so using WebSphere j/s which I know you know a lot of people don't like and there are a lot of issues and criticisms about its API but it is the most popular one and it is one we're gonna talk about today and and this is how we how we do it correctly we have the my contract contract instance and we we do dot methods get count and once we have that specified we call dot colony and we get one value right that just happens by itself as in like one-off and for contract events if you have a WebSocket provider you can subscribe to it and do all these different things but if you don't and you want to make sure

that you write your dab so that you don't assume people have certain types of providers we have my contract get past events and that would just give you all the events with that particular event name and finally contract state there's just no way for you to right now use well 3oj as to just give me all the hot contract stay it's just not possible now unless you you know take the logs and decode them and stuff like that so we're presenting today something called drizzle your tails and it's it's not really related to drizzle completely it's a completely separate library drizzle will actually use it under the hood but think of this as a completely separate library but we call it drizzle because it's kind of attached to the front end side of what we're doing at truffle and the main thing to take away

from this is we're using rxjs everywhere for this and if you're not familiar with the rxjs it's a stream based library so we're gonna think about not in terms of variables of what this variable is storing at a certain point in time but rxjs you know thinking in streams and observables allows us to abstract away the concept of time itself that sounds really wishy-washy but it sounds cool so that's what I said alright so let's go through an example right we're gonna come up with a very very simple increment counter I mean that's kind of what we do as front-end developers right I'm not sure I don't think there are too many front-end developers here but we're always about the increment counter because it's the simplest thing you can implement that has some kind of state into so we have

the cast McCann or smart contract all it stores is a Yuen's count of 0 notice that it's not a public variable so we got to have the get count getter function we have that and then we have the event called update which basically gets updated get submitted every time the increment function is calling so very simple you call increment brings up number and image in the event and well first of all how do we use drizzle details we set it up very simple we require we import it either via command J S or ESX imports and then we pass in your web serie as long as the web 31.0 it work fine and then you know because it returns a

promise you gotta wait it and you get your drizzle utils instance and it does a little bit of magic behind the scenes but not as much as drizzle does it doesn't create a redux store for you behind the scenes its Yossi later on it's a little bit more pluggable and for the first example at the method call stream write what we had what we have from above here is the traditional web 3 way of doing it I said that before you know you call your my contract methods get count and nothing actually happens until you do dot call on top of it and this is again one off right with drizzle you tails we take the first part of that so my contract methods get can that's the actual method you want to call right and then you pass that into what's called a create call stream function so

in rxjs the convention is the dollar sign represents stream so the way to read that is like const can't stream equals a wait drizzle utils create calls stream and we pass in that particular method call and what happens after that is once you have the can stream variable you just called dot subscribe on it and update your state and you log it out do whatever you want right so it's really interesting because now you have two lines that'll basically make that call for you every time there's a new Block in the chain similarly for event stream you know like I said before this is how you do it in the web s web 3 the current web 3js method but with drizzle your tails you

call drizzle your toes create event stream pass in your truffle contract artifact we might support other things later on but and then you create the event stream now the here's the interesting about interesting thing about rxjs is you can map filter merge you can even do higher-order observables make a p.i calls on these particular events and trigger those sorts of things right so for this particular one notice that the event stream represents all the events that this contract will give us but if we're only curious about the update event we pipe that stream through a filter and we want to filter for only to update events and it's that's just very simple example of the things that you can do with streams it there's I mean you can do an hour talk on the different operators that you can

do an rxjs streams but but this is not an rxjs tutorial so but yeah so once you have that you subscribe to it update your state very simple as you can see like three four lines and finally the contract state stream where you want to create a state stream with the truffle contract artifact by so we pass in the traffic on a contract artifact we call create state stream and are we gonna get the state stream variable and you know subscribe to it log it out for example or update your state and what you're going to get is something like this this particular JSON gives you the name of the contract the balance on the contract and also the variable is on on the contract as well with mappings a little bit more difficult because you need to know the keys so we don't really support

that Foley yet but for simple variables like this I think it's very helpful to just have like a dump of what's on the contract itself again you'll notice like before I mentioned in the contract it's not a public variable so you suddenly you don't need to even need to have like specific getters for a lot of these things you can actually just do these two lines and all of a sudden you know what your variable is so I think that's pretty Oh happened there let's go back okay is it hang is lagging oh okay sure go let's go back one slide can I

use the okay cool yeah and the other thing I want to point out was that as you can see under the account variable the value is one C because it's hex but that's all I want to point out next let's have a quick demo of those three streams that we talked about you know the the comment that the events and also state so this is a small gift Jeff give of a very basic DAP basically what we had from before and I'm just gonna play it you know very simple you know you have your account and it goes up every time you increment obviously this is happening very fast because it's instant mind on the ganache the truffle test blockchain so in real life you know you would have to wait for Rio block times

but the can itself is updated by itself you can see the contract state J's on its it's just looping the contract state J's on it's also updating and events are just flowing in right this whole entire thing is like a 30 line 40 line maybe about it's a little bit under 40 lines for the whole react component it's one react component 40 lines and if you take away all the UI logic all of this is actually just only ten lines of code right and it's it's all the stuff that oh yeah we had from I showed you in the previous slides so pretty cool right I think it's pretty cool thanks thank you thank you so under the hood how does this kind of work right not gonna go

into it too much but internally there's an rxjs stream that tracks each new block that comes through if you're providing a WebSocket provider we will basically use the web three SUBSCRIBE methods if not it didn't support that we actually use meta masks eath block tracker and there's a polling interval and you can actually specify that polling interval if you want and of course if you want to watch the new block stream itself right if you just called reso your tails dot new block stream that refers to the actually underlying new block stream and you can subscribe to it and or filter a map and do whatever you want within you get that block every time that there's a new block so a quick shout out to the people on Team Haseley been a longtime friend of mine helped me a lot with this

particular library and Harry Altman Mike sees Nick D'Andrea these these three guys did a lot of amazing work on the truffle decoder which is what made that the state decoding possible and at this point you might think it's the end of my talk but wait there's a little bit more all right so you know I was gonna set expectations right I got five minutes left that's perfect all right so get contract instance a lot of people say you know I hate truffle contract I don't like to use in the front end or it's breaking my test and things like that I understand it I get it you know you like your web 3js or ethers or whatever so we're using web sweet ideas here right we have a convenience function here so these are all just gonna be convenience functions you can pass it a trap for artifacts or

an ABI and or a dress and it would just give you the well 3gs contract instance the deployed instance as well right just if you're gonna use drizzle your tails you might as well it does the same thing as what you would do manually with web 3gs second thing is current account stream so a lot of times for UX you know we want to make sure that the person using your DAP no is that what knows what particular account that they're on so when you switch accounts on meta masks you want to just be able to subscribe to it and get that new account and update your State with it right well now you can it's just literally just one line I I mean it's two lines here but I it's it is one line you know what I mean right like yeah just convenience functions and finally my

favorite convenience function is the get web 3 convenience function because for the longest time we just copy and paste this chunk of code that'll get the web 3 from what used to be Windows web 3 and it became windows a Syria and it's just a lot of work that I mean it's 2019 who has a time for all this right so yeah you can so it's a separate utility from like the main drizzle utils core but it's part of the same mono repo just because but um yeah so we require it and it we can pass in your options what are these options let's find out the first thing you want to do is what this is the actually order in which we decide which provider to use you can provide yourself a custom provider and that'll it'll always try to do that but

if you don't it'll actually fall back to the window you see I'm the minimized injected provider if that doesn't exist then we look at window to work with three to see if you using a legacy injector provider if none of those three exists then we actually go to the fallback provider which is something you can specify this is kind of confusing and some people at first it's like what's the difference between a custom provider and a fallback provider well it's very simple a custom provider is always checked first fallback provider is something you want to put there just in case and of course if you put nothing at all as you know as it is when you're really lazy and you're just developing something very small and quick it just defaults to the development provider which is nine five four or five on the local it's not eight

five four five because nine five four five is what truffle develop console use there's been a lot of talk about about should we standardize all out of it and eight five four five probably but the state of things indicate that this is the case we can have that discussion on the github issues I welcome more discussions on that and all things all the things that you saw today are supported on the browser server-side nodejs of course and react native so you know you can make your your cool react native apps with this as well and that's pretty much it if there's one thing I want you guys to do today is to take a picture of this slide on the upper or like under the upper one the upper QR code is that link directly to drizzle

you tails you can do NPM install drizzle you tail stuff today and thank you so much I'm gonna see you guys hopefully as many of you guys as can come to traffic on 2019 it's gonna be held in August sponsored by Microsoft so it's actually getting held on the Microsoft campus in Redmond the link to that particular event is the bottom QR code there so that's pretty much it for me see you guys next time [Applause]