Interacting with Smart Contracts: The ABI Array

The course is part of this learning path

Interacting with Smart Contracts: The ABI Array
1h 1m

This course covers Ethereum denominations, the ABI array, Ethereum networks, private/public key cryptography, and much more!


In this lecture, I want to talk about the ABI array. We've briefly talked about it before but now I want to go a little bit more in-depth what it means and what it's used for and and why do we actually need that. Now, the ABI array stands for Application Binary Interface. And the reason why we need it is because our smart contracts like this one, like the game manager here, they are getting compiled into byte code and then they run on the Blockchain. Let me give you an example here. They just run on the Blockchain. Obviously, you need more gas. All right, now we go they run on the Blockchain under a specific address. And here in remix you have this beautiful little interface that you can interact with your smart contract and there are some it's, basically, an html side with buttons and input fields where you can input the arguments that your functions need that they require and why does remix knows this? I mean, it's just html and JavaScript. There is no magic behind it. It's not like magically looking into the Blockchain that it has running here and can determine the arguments and the function names. There must be some other way to do that. This is where the ABI array comes in. If we are interacting with the Blockchain, like get the top10 list here and I hit the 'Debug' button, then we can see that we once, you see on the left side here that it's highlighting specific parts in the code, where it's just jumping inside. And when we see where it actually jumps into the top10 function and you see here there's a jump destination operation here and then we go one back, a little bit back, then we see that it's somewhere a little bit more back, somewhere it finds a way to determine where it should jump into this function and the way it finds this is by getting, and I hope I can get there, it's a little bit hard here. Here we go, by finding the right entry point into the function. And when we compare this down here, then we have an, in the transaction that we just sent off to the network, there is an input and that input is encoded in a very specific way. And when it hits the EVM and the transaction is sent off to the network and then the EVM runs through the code here. It's, basically, just running one statement after the other until it finds the same identifier for the function the getTop10 function. And then jumps into the right position of the code and then runs through the rest of the logic inside the function and then until it hits a return statement and that's like one function after the other and at the beginning it just determines where it should jump into the code and the way this is calculated, the way this is done is deterministically calculated and it's the Kazakh or part of the sha3 hash of the function signature. So, you don't have the actual functioning, there is no getTop10 inside the actual code, there is just a function signature. And the way this is calculated is by taking the sha3 hash of the function name including the arguments and you can't read that out of the code here what was the original function name. You cannot go back because it's a hashed value. So, somehow, you need the information how the functions are called plus their arguments, their types beforehand and this is where the ABI array comes in. So, when I go to the Compile tab and I hit the 'Details' and I look at the the ABI section, then I see the whole interface, anything how I can interact with my smart contract is in the ABI array. So, when I open it then I have my type function, name, and a winner, doesn't have any outputs but it has one input, an address. The name is not so important but an address. The name is only important for remix to generate these input fields with a hint with this placeholder here, address_winner which gives you the the variable name here. And if you go to getTop10, it must be somewhere here, getTop10, then we see this is a constant function which means previously in all the solidity versions, there was constant and writing functions and now we have a view and pure functions instead of constant functions but the ABI array stayed the same. It just tells the JavaScript library outside that this function is a reading function. So, as soon as this is constant in the ABI array, then remix will make it a blue button and we'll call it a call instead of a transaction. So, it's going to be a reading operation. Now, as I said, these inputs here, let me just copy this here and go down to the Console and paste it here. So, these values are deterministically calculated, it's not coming from a random value and you can calculate this yourself. So, I just pasted it here to have it as a reference value. And in this Console, you have access to the web3 object. So, web3 is here and if you go to web3 utils.sha3, then you can calculate the sha3 hash of a string. And in our case, the sha3 hash is going to be getTop10 without any arguments. And that will give you a very long hash of the string getTop10. And if you take the first four bytes or eight characters without the 0x, obviously, so you have 12345678. Then, you have the so called function signature and in a classic JavaScript library where you have to have the ABI array they parse this array. They go through every single element of the array. And then, when you want to interact with your smart contract, they will offer you a nice way to call getTop10 function and internally they will transform it into this this hex encoded hash of the function signature and then send this off as transaction against the Blockchain node and the Blockchain node will just run through the code and give you the right results at the end back. So, you go around here and then at the end we have a return statement. It's pretty long code because we are putting together this this 10 elements array for the addresses and the places, the number of wins. But in general, you have somewhere a jump position inside the code and then it's doing the lodging inside the code and then you have the return statement and then the transaction is finished. And the way you go into the code that is determined by this function signature where you get the name out of the ABI array. All right, let me give you a second example enterWinner and I know this is going to fail here, but let's just. So, we go enterWinner I can't do it but we still have the input. It's going to be here input, let me paste this one here. So, you see we have a lot more input here. Now, we have the first eight bytes, one to the first four bytes, eight characters, is going to be the function signature. 12345678. So, d2add17b is going to be the function signature and then appended to it are the function arguments. Let me give you an example. And it's going to be appended to it, 256 bits in this case. And there's a rule for this and it's in the Web3 Js documentation. If you go to the version1 and if you go to the solidity documentation, which I have opened here, which is on the, then you can find the formal specification for the encoding in contract ABI specification and formal specification for the encoding. So, if you really want to dig into why these things are encoded the way they are encoded and you want to maybe write your own library. If you're more into those things, then you can find all the specifications here. For us, it's suffice to know that the way this is encoded is first you have the function signature and let me give you this other example which I promised you we have an sha3 of enterWinner. And here we have an argument and we have to add the argument type into the round brackets. And from there, we actually take the first four bytes which is the first eight characters but only from the whole hex string so we have to add this 0x as well. So, if you take substring(0, I think it's 10, then we should end up with 12345678 bytes and this should be the same as our input field at the beginning. Let me paste this again here. And after that, we have the actual argument and this is padded to 32 bytes or 256 bits. All right, that's it. That's the whole details about the ABI arrays. There is not more that you should, actually, know about that. That's the reason why you need it because in the EVM as soon as the smart contract is compiled you don't have access to the names anymore but you need somehow to get access to the names in order to find out how to jump to the right position. Obviously, you can also put your input field, your data field for the transaction together yourself if you run for the debugger if you know what you're doing. But if you want to have it from a high level perspective, if you want to work with external libraries, then you need this ABI array. All right, I'll see you in the next lecture where we are going to discuss the different Ethereum networks because there are a lot of them out there.


About the Author

Tom is a CTO, senior back-end developer, and systems architect with over twenty years of hands-on development experience in a variety of languages and systems. He has a CS master's degree and has been working with Ethereum and blockchain technologies since 2016.

Covered Topics