 My name is Rain Revere and I'm a smart contract developer. I'm the lead architect at Shapeshift Prism and I'm also the co-founder of Maiden. I've been doing smart contract development for a couple of years and our team has learned so much along the way and it's really an honor to be here and to be able to share some of those lessons with you. And it's especially an honor to be one of the few women up on stage. I'm a trans woman and I love this work and the community is so amazing and so it's such an honor to be able to share some of this expertise and really dig into the details. So when I was thinking about what I could possibly share, I wanted to give something that was really practical and so this talk is going to be pretty straightforward. We've got lots of things that we learn doing smart contract development in the real world so that means production level handling lots of Ether on the live network which as you can imagine has a lot of responsibility that comes with that. So what you can expect from this talk is that I'm going to go from low level to high level. So all of these are pretty practical tips for all the smart contract developers in here and I'm going to start with the code and we're going to go over some details, some patterns that I've learned and our team has learned from and then we're going to end on some higher level patterns especially when it comes to being a leader on your team. How do you lead as a smart contract development engineer? So first the low level patterns. Central logging is something that took me a little while to find my way to and when you design your smart contracts, you want to modularize things, right? We all know that as software developers but there's some quirks in the EVM at least at this time that you may not think about ahead of time but actually lead to a system that is more maintainable and is able to respond and communicate with your server or whatever other architecture you have. And one of those is what I call central logging. In a multi-contract system, logs or events that are fired are really an important way to track what's happening on-chain. All of your off-chain activity is going to be based on different events that are firing and when you are firing events from different contracts you generally have to monitor those events separately so each contract you're going to be watching those events and so if you have a multi-contract system there's actually a lot of benefits to using a single logger contract and so when you have a single logger contract all of those events will fire from the same contract and are easier to monitor so let me just show you how that looks. So here's an example of the logger contract and what we have here is a whitelist that maps addresses of contracts to a simple boolean that says whether it's been approved or not. So this is where it handles multiple contracts. So those addresses are of contracts and you have a modifier that's a simple requirement that the sender is indeed in that whitelist and so the modifier whitelisted is provided here and then you can have any event, here the event is called registered so that's the red text with the two superscripts and the registered event is simply forwarded from the log registered function. So if you have the owner which is provided with the owner super contract and then the only owner modifier, pretty standard you can have an owner contract that is able to register all the contracts in the system so contract A, contract B, contract C all of those would be an authorized contract to be able to register those and if that authorized address was set in creation then you know exactly who has the ability to register new contracts and then those contracts have the ability to call log registered or any event. So that's an example of central logging and that's been super helpful for us to be able to handle large numbers of events from lots of different contracts in a multi contract system. The next one I want to show you is the idea of modular libraries. So libraries in Solidity, if you're not aware already are a way of deploying code once that other contracts can use over and over and when you have a multi contract system or you're deploying a new contract for every iteration of something there's a lot of gas costs in that and if you can reference, if you can link a library that's going to save a lot of gas compared to implementing compared to deploying all the contracts again. So libraries are well known to provide that gas saving mechanism and the idea of modular libraries is the idea that you can link multiple libraries together in order to provide some abstraction layers. So these are all like architectural patterns for you to have more maintainable smart contract code. So what does this look like? A modular library is one in which the contract itself doesn't have to know about all of the different modules and so it's a way to encapsulate functionality within a library in order to have some separation. Now libraries are linked and all of the calls end up appearing internal so this doesn't actually provide, this is more of an organizational strategy than changing the actual access levels. So here's an example for the Prism Projects we have a library called Prism Lib and there's a lot of different pieces of data and libraries that have functions that operate on that data and as a way to break it into smaller pieces one good method is to have a data struct in each of the libraries that's defined in each of the libraries and then that can be included in the contract and so you have nested levels of data so the struct is defined, you can see in the blue with the number one is the data struct and then that's being expected to pass into each of the functions so the rebalance function on the Prism Lib is going to ask for the prismlib.data and then the nested nature comes from the fact that portfoliolib has its own portfoliolib we can assume is that libb and it's being imported somewhere else so portfoliolib we can assume has its own data struct so portfoliolib can be accessed the functions can be called in portfoliolib and the data is contained within that lib and so there's an abstraction there if you notice we're not passing the entire prismlib.data to the rebalance portfoliolib.rebalance function we're only passing self.portfoliolib so the second red instance number two and so that way portfoliolib.rebalance or any other functions in portfoliolib don't have to know about anything else in the data so this ends up being a pretty standard abstraction and hiding mechanism but something that we haven't seen a lot about in the wild with library development but we found it to be a really great architectural pattern for prism so now we get to the last of the low level patterns that I want to share with you and this is a higher lower level pattern and this is an idea that has been shared in other talks here the idea of the blockchain as a court system and this didn't come to me until much later in the development of prism but the opportunity to save a massive amount of on-chain computation exists when you treat the blockchain as a court system or an arbiter which means that you assume that parties are acting in best with goodwill, in best interest but you have a mechanism that if something goes wrong, if one party says the other is not fulfilling their obligation then you can run an actual smart contract as if you're bringing it to court and when you run that, when you execute that smart contract then you're using the blockchain to orbit to be the arbiter of that transaction so what does that look like? so here we have a contract this is just a general, you have some users and there's going to be a counterparty the other end of the deal and you're using the smart contract the naive approach would be to execute everything on the smart contract when you have arbitration built in then instead, as I described you assume that both parties are acting cooperatively and correctly but you have the mechanism in place for a dispute resolution process so the top interaction here is where the user, through the smart contract interacts with the counterparty there's not any execution there's really nothing happening there there's not code that's being executed on-chain maybe just a hash that's stored that both parties can use to evaluate off-chain what's happening so user A maybe sends some ether to the contract after a certain amount of time the counterparty is expected to send ether back or some transaction occurs and at this level it's really up to the counterparty whether they want to do that or not now if the counterparty doesn't do their part you have a time window a week, a month, whatever the time window is where the user can file a dispute and that's all on-chain so there's a time window, the funds are locked up and so imagine user B has a problem and says yeah the counterparty didn't do their job so they send a dispute resolution transaction and this time the whatever business logic needed to be executed which could be quite expensive is going to be fully executed and because it is deterministic the winner of the dispute will always win so the beauty of this is that the incentivization is such that if you know you're going to lose you would never do the wrong thing so the counterparty has zero interest and the reason you force that incentivization to be aligned so strictly is that you say if you lose the dispute you basically lose all of your money so you punish the person for behaving against the expected behavior and so when done right there's really no incentive to go against the expected behavior you have user A acting expecting a certain thing back from the counterparty or the counterparty doing their job the threat of the dispute resolution process incentivizes the counterparty to do their part and the beauty here is that you're not actually executing the full contract logic on chain it's just user A doing their thing and the counterparty doing their thing so I see this as a potentially huge pattern that can be used across smart contracts in order to optimize reduce execution time and this is something that could be put to good effect on a lot of projects okay how's everybody doing you still with me the developers are the developers are like yeah this is cool okay so we have some higher level patterns and these are for you as well these are also for developers if you spend more than a couple years working in the software industry I hate to break it to you but you're going to have to do some things other than coding you're going to have to learn some other skills and some of those are going to be technical skills and some of those are less technical but what are the higher level patterns that allow you to be successful as a smart contract developer not just when you're in solidity land working with your team when you're making judgment calls when you're making important decisions about the direction of your product that the rest of your team is looking to you for so one is something that I call role analysis this isn't a technical term but role analysis how do you analyze the roles in the smart contract and this is something that you can use this is simply an approach to smart contract development and design and you can use it at any stage of the process so if you're designing a smart contract from scratch who is interacting with the system that's the main question you're asking here who is interacting with the system and what are their incentives and how does the behavior how are their behaviors going to derive from the functions that you expose to these different roles so I use this both in the design process but I also use this throughout the entire career of the smart contract system when you're iterating and you're adding new features there's always going to be adjustments to the behaviors of the different users and the different roles that are interacting with your system so to be a really good smart contract developer you have to understand all of the roles of individuals interacting with your contract what their different incentives are and how that affects the overall functioning of the system this is like the essence of the game theoretic nature of decentralized smart contracts so just some examples the prism contract for shapeshift prism has a few simple roles it has a buyer, a seller, and an oracle and with prism the buyer purchases a contract, a portfolio of different digital assets the seller is putting up collateral to ensure that those assets can be paid off depending on whether the portfolio goes up or down and then the oracle is another entity that's providing the prices that determines the value of the portfolio so different roles and even these simple three roles have involved a high level a high degree of analysis an ongoing analysis and the trust implications are well understood as the contract develops and becomes more sophisticated another example is a salt loan let's say you were doing a loan that was backed by digital assets that was collateralized by digital assets in this case you have a borrower someone who's borrowing cash and then you have a lender who's offering that cash but then locking up the collateral in this case you have salt as a kind of multi-sig arbiter to make sure that if anything funky happens with the other two salt is in there and can have the last word this is an example from a talk yesterday the liquid pledging contract was really I thought really brilliant idea to combine fund management with liquid and here there could be many arrangements but a simple arrangement is to have a giver who's providing some ether and they want that to go to a good cause or a good project they don't have time to do that themselves or they want to trust someone else so they delegate that to another role and that delegate is going to choose the project and eventually a reviewer is going to say yes these milestones have been accomplished and that goes through a simple concept but it goes really far and it really is what can separate someone who just knows solidity from someone who can design maintain and scale smart contracts on a live network context dependence is another skill that comes with experience and is something that is really valued on a team and by this I mean analyzing when one action is true in one situation the same action might not be true in another situation I know this is really scary for a lot of you I didn't get into development to deal with fuzziness and ambiguity either I love really straight forward and deterministic systems but the truth is any complicated problem is going to depend on a lot of context so one example in this space is that you hear a lot of best practices best practices are great but when they turn into hard and fast rules you can really miss out on the nuances of the situation so one I see a lot is send versus withdraw patterns and the advice out there is to always have the user withdraw never do a send so it's like push versus pull never do a send and I actually don't like this advice because it's often just taken without much thought why don't we do a send well we don't do a send because there's vulnerabilities if you're trying to send to multiple people you have to be aware that any one person their fallback function could throw they could use up all the gas they could use up most of the gas so there's risks to sending to multiple parties okay I understand that there are also situations where maybe you don't want for the user experience they don't have another transaction you don't want them to have to do that transaction so maybe the send would be appropriate in those cases keeping in mind this dictum of it depends on a professor in grad school who this was in my counseling program and it was beautiful every time anybody asked well what if you're working with this client and they do this what should I do she always answered she thought about it and then she said well it depends and that would be her answer every time so with skill and experience comes an incredible awareness of context and that's what makes you to think about context dependence and lastly I want to say leadership in blockchain at the developer level because contracts are immutable technical debt is much costlier so when you're making decisions as a lead engineer you have to make a lot of judgment calls because that code might be on chain for a long time and that's something to keep in mind thank you so much I'm going to share go over the patterns we talked about central logging modular libraries and arbitration as architectural patterns at a lower level and then at the higher level I hope you can take some of these concepts away about leading your team being more dependent on context and then bringing role analysis to everything you do thank you very much