Ethereum Beginners' Guide #2 - Smart Contracts

in #ethereum7 years ago (edited)

Hey, you've found step 2! Good for you! Did you miss step one? It's rather important; go back here and do that first.

This is the second guide in getting started with Ethereum, written by me, a developer, to you, a user. As I mentioned in the first guide, the whole Ethereum ecosystem wants to be a "major version upgrade" to the current way we interact with "the internet", and like any major version upgrade, there's some new reflexes we need to learn, and some of the old reflexes from the previous version aren't useful any more. That's what these guides are for; to start you out as a user, getting some repetition under your belt so these new actions start to feel less strange and awkward and more like a reflex you don't have to pay that close attention to.

One other important reminder from the first guide: Ethereum is "decentralized", which means there's no trust built in. To stay safe out here, it means you must operate from a default position of everyone's a con man, including me! I'll give you steps along the way that enable you to verify your actions.

1. Send ether

All right, the first step we're going to do is send some ether to someone. Now, to the 8-year-old with the fidget spinner who just said "But I already did that! It was the last step of the previous guide; I'm skipping this step", you're going to get kicked. What you did in the last step of the previous guide was send ether to someone using Coinbase. Coinbase is a slick web interface that makes it easy to do that. But "making it easy" for you really means that it abstracted away a some of the complexities of sending an Ethereum transaction. You are not some lap dog, content to get your nibbles delivered on a silver tray and your Ethereum transactions delivered by your butler; no, for that butler just made off with your fine silver! You are now owner of your own Ethereum wallet and you will not have to rely upon others to generate your transactions!

To understand how an Ethereum transaction carries your instructions from your computer to the whole world, we need to introduce the concept of gas. In this instance, we're talking about fuel for a vehicle, and not your uncle on fiesta night. Transactions in Ethereum are "smart", which means they're technically little computer programs that you're asking the world to execute in the vast supercomputer that is Ethereum's blockchain. So, there's a series of instructions that get evaluated. The simplest instruction is a simple "pay X ether to Y from Z". This sort of thing's not that complex, and indeed most cryptocurrencies (like Bitcoin) have transactions that are those instructions. The difference is, in Bitcoin, that's pretty much the only instruction you can give. In Ethereum, there's many more instructions you can give, but with that power comes great responsibility cost. Because Ethereum is a worldwide computer that anyone can run a program on, it needs some way to stop an attacker from using up all the computing power and blocking anything else from happening. So, Ethereum charges for every action it takes. Every action Ethereum can do has an associated cost, which is given in units of "gas" (it's "fuel" for that transaction). The simplest "pay X ether to Y from Z" transactions cost about 21,000 units of gas. When you send a transaction, you also have to indicate how much ether you're willing to pay for every gas unit (called your "gas price"). Since this value is often going to be a very small fraction of an ether, it's usually expressed in wei. If you were willing to pay one billion wei (1,000,000,000 wei, a.k.a. "1 Gigawei" or "1 Gwei" or "0.000000001 ether") per gas unit, for 21,000 gas would cost you 0.000021 ether for that transaction. At the current (as of this writing) rate of about $300 USD per 1 ether, that's about $0.0063 USD (a little more than half a cent) as a fee to send that transaction.

Paying for gas helps keep spam off the network, but it also provides a means for you to get your transaction priority treatment. The Ethereum nodes that are adding transactions to the blockchain (the "miners") are looking to make a profit for themselves. They get to keep the gas cost for transactions of yours that they finalize. So, if you say you're willing to pay more for every gas unit, that's an incentive for them to roll out the red carpet and process your transaction now, rather than giving it the DMV treatment.

When Coinbase sent on your behalf, they picked the gas price for you. But now you're going to send a transaction where you get to pick the gas price. To do so, we're going to use our downloaded copy of MyEtherWallet again to do so. Go find that downloaded ZIP again, and double-click the index.html file in it. In the top-right corner, make sure the "Node" dropdown says "Node: ETH (MyEtherWallet)".

Now, click on the "Send Ether & Tokens" tab, pick the "Keystore file" option, select your Keystore file and enter your password, and finally click the "Unlock" button.

Got all that? Good for you! You're getting to know the technical terms and practicing pulling your Keystore file from wherever you're keeping it safe, and keeping that password on the forefront of your mind. If you're forgetting what those terms mean, head back to the first guide and remind yourself of the five pieces of data you have that embody your Ethereum wallet. 

Once unlocked, you'll see a sending form that's fairly similar to Coinbase's (you have a "To" address and an "Amount to send"), but now you can also see a "Gas Limit" field that's already filled in with the default 21,000 units I mentioned. But what's missing? What's the second variable I just told you about? C'mon think... Do you have it? I'm putting enough words here between the question and the answer so your eyes won't see it before your brain does; are you caught up, brain? The price per gas unit isn't here in the form (did you get it? Have a cookie: 🍪). MyEtherWallet does give you control over the gas price, it's just not in the form itself. It's up in the upper-right as a drop-down. They show it as a slider, so you don't have to enter a specific number, you can just pick where on the slider (from "slow" to "fast") you want your transaction's priority to be. Since we're not in a hurry (you've got a bunch of reading left to do, and besides, I know you just love spending time with me), crank that sucker all the way over to "slow".

Now, enter 0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359 in the "To Address", and enter half your balance in the "Amount to Send" field. Then click "Generate Transaction". You may note that MyEtherWallet bumped up the "Gas Limit" as you did so. That's okay; the "Gas Limit" is a maximum number of gas units you're willing to purchase. If your transaction takes less than that to run, you won't be charged for unused gas. Click "Send Transaction" and MyEtherWallet will pop up a final notice showing what you're about to do. Click the "Yes, I am sure!" button to send the transaction to be finalized.

Congratulations, you sent your first transaction all by yourself! 🎓

Actually, no, I'm quite offended; give that mortarboard back! Do you even know where you just sent your funds to? I told you to put in an address in the "To" field. Is it my address? Did you just pay me a tip for writing this guide? Or perhaps this entire guide has been copied from its original location by someone, who modified that address to be a wallet owned by that political party you hate and now you just became one of their donors! So, even if I tell you that address is mine, how can you be certain? You can't take my word for it; I told you not to. So, what do you do when you want to learn something? Ask the Google. Seriously. Copy that address and do a Google search for it. What do you see?

Well, the first few results are likely to be Etherscan and other block explorers who recognize that address. Visiting the Etherscan page about that address, we can see it's received a hefty amount of ether, but who owns it? You should see that Etherscan has labeled that address as "FoundationTipJar", and if you look at that other search result further down the list (always good to check multiple sources), you can see that address is listed on the https://www.ethereum.org/donate website as a donation address for the Ethereum Foundation. So, you just made a donation to the hard-working developers who are striving to make Ethereum even better. Great! I didn't kick you in the head on that one, but that's a warning...

Now, what's actually up with the transaction you sent? You set to be "slow", but how slow is "slow"? Well, we know "fast" is 10 seconds or less (because new blocks are added to the Ethereum blockchain every 10 seconds), but if your transaction doesn't get in the next block, when will it? Well, let's go check on it.

Head over to https://etherscan.io, and enter your own public address in the search box. On your address' page, you should see the recent transaction you sent. Is it confirmed? Great! Even a "slow" transaction should confirm after a few minutes or up to an hour under normal network conditions. But there might be something happening on the network that is causing a log-jam if yours is still stuck. One tool to help figure out how long it may take is the Ethereum Gas Station's Gas Calculator. That website monitors the live state of the Ethereum blockchain, watching what transactions are getting confirmed and seeing how much they're paying for gas. Enter the gas amount and price you entered in your transaction, and it will estimate how many blocks/minutes it will likely take to confirm. So, if it's still unconfirmed, leave it alone for now, and check in on it later.

2. Doing something with ether

So, enough with these blasé transactions that just move ether around, let's do something! In Ethereum, you can craft instructions like "if A, then pay X ether to Y from Z". Having an "if ... then" structure inside the transaction itself is what separates a simple "IOU" from a Contract. It's even more powerful than a real-world paper contract, because it cannot be separated from the payment itself. In the real world, you could draw up a contract on paper saying "If Bob mows my lawn, then I will pay Bob $5". You could get both you and Bob to sign it, get it notarized and have it be all official. Then Bob mows the lawn and says he's done. You say "yup", and write him a check, sign it, and hand it to him. That works well enough in most cases, but what if the check bounces? Bob can't un-mow the lawn. What if you realize Bob only mowed the front yard and you want to cancel payment? Well, you could call to stop the check and find out that Bob's a pretty fast runner and made it to the bank and cashed it already, so you take him to small claims court, where he trots out a character witness who knew you in the fourth grade and said you pushed them on the playground, so you don't get your money back. Not the most effective. The issue here is that the payment itself (the check, and your signature on that check authorizing its payment) is detached from the contract. The check itself doesn't know about the contract, and the person cashing the check doesn't know about the contract. With Ethereum contracts, you can write as complex a statement as you need to satisfy your needs, like "If Bob mows my lawn before July 12, then I will pay Bob $5, which can be cashed no earlier than July 20, so long as I have reported no fault in his work before then." In that way, the Ethereum payment is part of the contract and can be fully-aware of the state of the contract, making everything much more transparent and verifiable.

Creating these contracts is a whole separate topic, which we're not going to get into now. What we're going to learn to do first is interact with one that already exists. The example I gave of Bob doing an absolutely terrible job on your lawn is a one-shot contract. Many contracts on the Ethereum blockchain are designed to be used and re-used many times over. As an example, think of the loyalty program at your local frozen rat emporium: "Buy 10 frozen rats and your next one is free". That's an open-ended contract that has several phases, and has to keep track of what's going on at each point in the process. If you want to participant in this amazing offer, you first sign up (so your future purchases are tracked), you need a way for you and the frozen rat emporium to know how many purchases you've made (so you can tell close you are to hitting that 10th frozen rat purchase and earning another furry popsicle), and a means to trigger getting a free frozen rat (once you've rightfully earned it). And once you've gone through it, you can do it again! In the real world, if your local frozen rat emporium is rather lazy, they could implement this system with minimal fuss by every time someone buys a frozen rat, they also get a snail shell (because snail shells are cheap and useless on their own). Then, anyone can turn in 10 snail shells and get a frozen rat. In this way, the frozen rat emporium has used something that's useless on its own (a snail shell) and given its customers a reason to want to collect them, and a means to redeem them (Yay! A yummy frozen rat!).

In Ethereum, there's many contracts that do this, termed "token" contracts, providing some means for you to be given a token of some sort, a means to transfer them around, and possibly use them for some purpose. Whatever the "token" is that the contract issues, it can pick a name for it, define how to get them, how new ones are created (if at all), and anything else about them. Tokens can be set to have a set amount to begin with, and never have any more created. For those types of tokens, they can represent ownership (shares in a company), membership (voting rights on some action), a scarce resource only some people will ever own (Alpha-edition Black Lotus Magic: the Gathering cards), or whatever else the designer of the contract wants.

So, let's look at a real example. You've actually already interacted with it; the Ethereum Foundation Tip Jar actually has a contract associated with it that reads "If you donate over a certain amount, I'll give you a Unicorn token". Sweet, my very own Unicorn! 🦄 But wait, how much is "over a certain amount"? Well, the contract is written such that the price can change over time, so you need to go see how much the current rate is. Let's use Etherscan again to explore this contract. Head over to https://etherscan.io and enter the Ethereum Foundation Tip Jar address (0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359) into the search bar. 

Now, on that contract's page, switch to the "Read Contract" tab:

Etherscan has analyzed the programming of this contract and found 11 different actions that are free to use (they don't change the current state of the contract), so Etherscan shows them here for you. One of them is priceOfAUnicornInFinney, and currently (as of me writing this), it's at 2,014 finney. One "finney" is a thousandth of an ether, so that's equivalent to 2.014 ether. Over 2 ether?! That's more than $500 per Unicorn! Well, these Unicorns must be pretty amazing then! So... what actually are these "Unicorns"? Well, that tip jar points to another address (the unicornAddress) that is the definition of these "unicorns" (so they don't get confused with all the other unicorns from all those out-of-state unicorn breeders who might be fairy-dust-doping their herds). The Unicorn address is 0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7, and if you go to the "Read Contract", there's some information there that tells you that these things are called "Unicorns" (name), and there's almost 2,000 of them (totalSupply). Well, that's not helpful. 😒  What good are they? What can you do with them? 

Well, the answer is on the Ethereum Foundation's donation web page:

The unicorn token can be used as any other token: it can be sent to friends or to other wallets and can be used with other ethereum contracts.

So, the primary purpose is it can be sent to your friend! Yay! Here you go, friend! But seriously, the Ethereum Foundation Unicorns are meant to just be fun; it's a way to prove you donated, and that's about all they've made it do. Well, $500 is too rich for my blood, so me being the entrepreneurial sort, I got together with my crazy cousin Lenny who used to work for the carnival before it got shut down in that food poisoning scare, and came up with our own, even better Unicorns that are much cheaper to make! Yes, I said "make", these Unicorns are made, not found, and it takes quite a bit of skill to do, so its really a bargain what I'm offering to you!

Here you go, the contract's over here at 0x2DC588Af5eff094401b1F8016E74E7D46d9E7A31; create another transaction and send the rest of your ether over there!

Why are you looking at me all squinty-eyed? This is totally legit! Why wouldn't you trust something that Lenny and I labored over for at least 20 minutes? What? I told you not to trust anything I said? Well that was dumb of me. So, how are you going to trust this thing does what I say it does?

Well, how can you see the logic behind what that contract does? The actual data of a contract is all binary data that doesn't mean much. Using Etherscan you can see the contract's raw data, and that particular contract has data that starts out:

60606040526001805473fb6916095ca1df60bb79ce92ce3ea74c37c5d359600160a060020a03199182161790915560028054909116600160a060020a03331617905566038d...

That's just one huge hexadecimal blob, which even to me as a developer doesn't mean anything. To at give it some meaning, you can convert that binary data blob into low-level instructions for Ethereum's virtual processor: 0x60 is a command that means "push the next one byte of data into memory". We see the first byte of data is 0x60, so it pushes the next byte (which is also 0x60) into memory. Then the next byte is another 0x60, which pushes the next byte (0x40) into memory. If you continue parsing this way, you get what is referred to as assembly code, which looks like:

PUSH1 0x60 (`)
PUSH1 0x40 (@)
MSTORE
CALLDATASIZE
ISZERO
PUSH2 0x00b4 (´)
JUMPI
PUSH4 0xffffffff (ÿÿÿÿ)
PUSH1 0xe0 (à)
PUSH1 0x02 ()
EXP
PUSH1 0x00 ()
CALLDATALOAD
DIV
AND
PUSH4 0x0f809adb (€šÛ)
DUP2
EQ
PUSH2 0x00c5 (Å)
JUMPI
DUP1
PUSH4 0x31719c69 (1qœi)
EQ
PUSH2 0x00e3 (ã)
JUMPI

Now there's some English words being used there, but that's still mostly meaningless. Even to me as a programmer, it's nearly impossible to make sense out of code written like that. Which is why most of the time, programmers don't write a contract in assembly code directly. Instead they create it in a more friendly programming language (for standard computer executables, the C programming language and its derivatives C++ and C# are good examples of that), which then a separate program analyzes and transforms into assembly code (a process called compiling). So, that's all well-and-good, but it still doesn't tell us what the code is actually doing. Going backwards from assembly code to another programming language is hard, but re-compiling something if you have the source code is relatively easy. So, I could give you the source code I used to create that contract, but how would you be able to verify that?

One option is that Etherscan as a block explorer has a feature that lets you see the source code behind the contract if the author supplies it. Go search for that address in Etherscan and note that there's a "Contract Source" tab for that contract. Click on that, and you can see a badge that indicates "Contract Source Code Verified". That badge indicates that someone (probably the author) supplied Etherscan with the source code for the contract, and Etherscan did its own compiling step and compared the output of its own test compile with the data that's actually on the blockchain. If the two match, then the source code is valid. So, since that address in Etherscan has source code listed, if you trust Etherscan, they're vouching that this is the source code for that contract. 

Now that you've got the source code in your hot little hands, what are you going to do with it? Well, you can do the same thing you do in real life when handed a contract and being told to sign it. You can either read the contract yourself and see if you can understand the legalese, or you hire a lawyer (who does understand legalese) to analyze it for you. For an Ethereum contract, the source code is written in the Solidity programming language, which has mostly english words and simple math operators, so you might be able to understand it on your own, for simple contracts. If you're going to be investing your life savings in a particular contract, it might be worth your while to hire a programmer (the same as you'd hire a lawyer) to go over the contract and give it a thumbs up/down.

Let's see if you can step through the basics of this contract, though: Looking at the code of the contract, you'll see many lines that have the word function followed by a name (like changeTokenOwner, withdraw, or setPrice), followed by an opening parenthesis ((), some more words, a closing parenthesis ()), and then an opening curly brace ({). Those lines define the functions this contract can perform; the actions that you can trigger. The things inside the parenthesis are the arguments to the function, meaning the data you can pass into the function to have it act upon. And the opening curly brace starts the logic of what the contract will do when that function is executed (there's a matching closing curly brace some more lines down that indicates the end of the function).

For just paying money to a contract and not specifying anything else, that action triggers the "failback function", which is a function with no name. So look for the function with no name in the contract source. In this contract, it's at the bottom of the source code, and looks like:

function() payable {
  assembleUnicorn();
}

The payable marker means the contract allows you to send ether to this function along with the command. The parenthesis are empty, so it doesn't require any additional data from you to trigger. And you can see the only thing it does is trigger the assembleUnicorn function. So, let's go find that assembleUnicorn function:

/**
 * Strap a horn to a horse!
 */
function assembleUnicorn() payable {
  if (msg.value >= pricePerUnicorn) {
    CardboardUnicorns cu = CardboardUnicorns(cardboardUnicornTokenAddress);
    cu.mint(msg.sender, msg.value / pricePerUnicorn);
    owner.transfer(msg.value);
  }
}

Okay, here's the meat of it. In order to understand what it's doing, you need to understand these four lines of Solidity code. The if line compares the msg.value to the pricePerUnicorn variable. msg.value is how much ether came in with the transaction. pricePerUnicorn is how much this contract charges per unicorn created. Just like in the Ethereum Foundation's contract, you can see its current value in the "Read Contract" tab on Etherscan (the value is in wei, so will look like a ginormous number. Divide by 10^18 to get the value in ether, if you prefer). The next two lines set up communication from this contract to another contract, and triggers the mint function on it, giving it the sender of the current transaction (msg.sender), and a fraction from dividing the total amount of ether sent by the price per Unicorn. The last line transfers all the ether sent to the contract to the owner of the contract. You can use the same verification process to delve deeper into the mint function if you desire. It's more technical, but it's a common sort of function that many contracts have to create new tokens and assign them to someone. If you got lost in all that, then your best bet is to do as you would if handed a legal contract you don't fully understand: either acquire the services of a developer you trust to evaluate it (or check out the comments below to see if other developers have vouched for it already), or trust you've got a "good enough" handle on it and go for it!

So the code shows that yes, when called, this function will create new unicorns ("minting" them) and attribute them to the address that sent the transaction.

Sound good? Okay, then now you're set to do that thing I told you to do: send all but about $1 worth of the ether you had in your paper wallet to 0x6954d0255cfeD71d55Ad8b371b4170B8BF7709dC (use the "Send Ether" tab in MyEtherWallet, put that address as the "to" field, and set your gas price to however fast you want it to confirm, then send), and cousin Lenny will get right to work creating you your very own, fully authentic, probably majestic, unicorns. The little bit of remaining ether in your account is needed for paying the gas cost in sending the other transaction, plus the few more transactions we'll do as part of this guide series. Speaking of gas, you may have noticed that MyEtherWallet bumped up the gas limit for this transaction; that's to be expected, since the Unicorn minting contract is taking more actions to create your unicorns than just recording the ether as received. So now you own some Unicorns. Do you trust me? 😏

Okay, so how do you query how many unicorns you now own? Well, in the "Read Contract" tab in Etherscan, in addition to the pricePerUnicorn value that you looked up earlier, there's a cardboardUnicornTokenAddress variable, which is a separate contract that actually keeps track of who owns what.  Search for that token address in Etherscan (0x69b5357D893fcE82248E83CCd9B0871F5D5d9461), and look at the "Read Contract" tab for that contract. There's some different options here, including a balanceOf function. The balanceOf function needs an input value of an Ethereum address, and it will output the token balance for that account. Put your own account address in that input field and hit query, and it will show you the balance of your account.

Is your balance zero? First go check and see if your payment transaction confirmed yet. If it's confirmed and you still see a balance of zero, which address did you pay? Did you copy the address I listed two paragraphs ago (starts with 0x6954d0)? If so, gotcha! That account isn't the Unicorn-minting account, that's just my personal account; thanks for the ether 💸 ! The proper Unicorn-minting contract I gave back many paragraphs, before the source code explanation (starts with 0x2DC588). If you sent ether to the wrong address, take this as a reminder to always, always check where you're sending your ether, then go transfer some more ether from your Coinbase account to your paper wallet, and then make a transaction to the proper Unicorn-minting contract so you have some majestic beasts of your own. 🦄

If you still have a balance of zero, one thing that could have happened is running out of gas. Go search for your transaction on Etherscan, and if you see in the details it has a red error notice like this:

Note that Etherscan is showing the "Gas Used By Txn" and the "Gas Limit" values are the same, and hovering over the "CANCELLED" notice shows that it was an "Out of Gas" error. In that case, your ether was returned to you (except the ether spent on the gas itself). Send the transaction again with a higher Gas Limit (for this transaction, a limit of 50,000 should be sufficient).

So great, now you have your very own mythical beasts, and at a fraction of the cost of one of those "genuine" Ethereum Foundation critters. Wait, who said something about "cardboard horns"? Who let an inspector in here?! Okay, yes, that's how Lenny and I kept our costs down, but those are high quality cereal-box cardboard horns, and eating all that cereal to create them was not easy, believe me!

So, in this guide you learned how to use your ether within the Ethereum ecosystem to trade for additional digital assets that also exist on the Ethereum chain. So even though your paper wallet is now pretty empty of ether, it still has value. The public address that your private key is associated with is now proof that you own several Unicorns, and in the next series we'll add the final layer of logic you need, which is moving your non-ether assets around. So, to summarize:

  1. Create an empty account: generate private key. From the private key derive public address. Account currently worth nothing.
  2. Receive ether: purchase from another human or exchange website. Account currently worth ether.
  3. Spend ether, receive asset: purchase from another contract. Account currently worth secondary asset.
  4. Spend asset, receive ???:

You can see that as we get higher in the "layers" here, that the value of the account overall doesn't change much (you are likely exchanging different quantities of assets to keep everything equal), but the higher you go, the more narrow the use for the asset. Ether is universally accepted by anything on the Ethereum blockchain. Ethereum Foundation Unicorns are known by a lot of people interacting with Ethereum due to the Foundation's visibility, so they have pretty broad value too. The HWACCH asset probably only has use to other users of this guide, so its worth is mainly due to it being a training tool. But in the next guide I'll introduce some new contracts that can only be used by people who already have HWACCH on-hand. So, stay tuned for that; I'll post a link in the comments below when that's ready!

Sort:  

Guide #3 is now up; check it out over here! ✨

Congratulations @midnight426! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You made your First Comment

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

You know, I was digging through the Smart Contract, trying to figure out where the address you said to send the ether came from (the "false" address) and was surprised it wasn't the address for the contract. Nonetheless, I sent it anyway, only to realize later I fell for yet another trap...

But it did have me thinking about a notice I have seen when sending money from Coinbase: they say do not send ETH directly to a Smart Contract address. Is that just not a transaction that Coinbase supports? Does it have anything to do with the cost of gas?

Thanks for the guide. Lessons learned!

I believe Coinbase has the "don't send directly to a smart contract" guideline because Coinbase treats all addresses as one-time use, so does not monitor them for returning funds once used. So, if the smart contract gives you a refund from your transaction, it would be sent to Coinbase's address, but they don't monitor those, so your Coinbase account wouldn't get credited.

If you use a Coinbase account to directly purchase HWACCH, then the HWACCH would be owned not by you, but by the Coinbase account that sent the transaction. You then wouldn't be able to do anything with the HWACCH, since Coinbase doesn't give you any control over using those withdrawal addresses to trigger any other types of transactions afterward. So, increased gas cost probably factors into it a bit, but mostly it would be a logistically harder thing for Coinbase to do if they wanted to support users withdrawing directly to a Smart Contract like that.