Вы находитесь на странице: 1из 38

dev_zl Follow

Dapps, web, and games developer. Interested in AI, blockchain, and smart contracts. You can
reach me at ledevzl@gmail.com or @dev_zl
Jan 14 · 8 min read

Ethereum Development Walkthrough (Part 1: Smart


contracts)

Smart contracts, ICOs, Mist, Metamask, Remix, geth, web3.. You’ve probably seen it all if you spent a
little time trying to get into the world of Ethereum developement.

Some deploy smart contracts to a test network, others tell you to read a yellow paper, while others advise
you to use the truEe suite because it’s great. And you are there, not knowing what exactly to do and how
everything works together.
dev_zl Follow
Dapps, web, and games developer. Interested in AI, blockchain, and smart contracts. You can
reach me at ledevzl@gmail.com or @dev_zl
Jan 21 · 9 min read

Ethereum Development Walkthrough (Part 3: Security,


limitations, and considerations)

The year is 2023, Dave is an administrator who will soon lose his job because a SaaS Dapp is basically
doing it now, and everyone’s in his ?oor. Still, as an honest worker, he is going to do his job well till the
last day. Dave was asked by email to send a sum of ether, and an address to a smart contract’s function.

So our guy opens up his Ethereum wallet a.k.a. a word document. He Eres myWallets.docx, and Ends 4
entries: My secret key, the company’s secret key, my password, the company’s password.

He opens Mist, Ends the Smart Contract he needs to send ether to, input 1000 ether from the company’s
account to the function of the Smart Contract, go back to his emails, and copy the address he must send
to the function. But, mistakenly, he doesn’t copy the whole address. He notices his mistake, and complete
the address manually, but mistype the last character. Now, it’s a whole new address.

Dave presses the send button, copy-past the company’s password, conErm the transaction and the
function is executed. Upon executing, that said function send ether to some predeEned account
addresses, and the rest of ether to the address that Dave typed in, through a self-destructing call, because
the developer who wrote it thought it was a good idea to clean out the blockchain from a smart contract
that is now useless (Spoiler: You can’t) after the execution of that function.
Coincidentally, the mistyped address is the address of a Wrestling contract from the Erst part of this
tutorial, that someone created mistakenly on the mainnet following the second method of the second
part of the tutorial.

Also, in the same timeline, someone found that Wrestling contract, registered as a second wrestler, put
ether in using the Wrestle() function, but the Erst Wrestler never played his round, and the second
wrestler’s ether is forever locked in that Wrestling contract.

So in this really improbable scenario(or is it?), ether was lost due to human error, and an incomplete
contract.

About the Wrestling contract


Although we implemented the base of our game, we didn’t thought about the life-cycle of the contract.
When it’s created, when it’s used, when it isn’t anymore.

What if a wrestler never plays after a few rounds? We should give the players the ability to withdraw
their money after a certain time, if one of them never plays their round.

We also need to think about when a contract will not be used anymore (In our case the end of the
wrestling). I said that, in order for a contract to receive ether, we should add the “payable” keyword to
the function that will receive it. But a contract can still receive ether through two methods (and there is
nothing you can do to refuse it), when a contract self-destruct(a special, pre-deEned function within
Solidity that will disable the contract and send all the ether it has to a designed address) to the address of
another contract, or when ether is mined to that contract. So, you should always keep a way to take ether
from a contract if it ever has more than it should.

In our case, since the winner will get all the ether oY the contract anyway, we could let him do using an
alternative withdraw function, like the following one:


1 function withdraw() public {
2 require(gameFinished && theWinner == msg.sender);
3
4 msg.sender.transfer(this.balance);
5 }

Wrestling.sol hosted with by GitHub view raw

It will let him withdraw whatever ether is on the contract, as many times as he wants.
When sending money in general, keep in mind that, for some reason, the process could fail, and you
should prefer to let the contract’s users withdraw their money than send them directly (like we did with
the Wrestling contract).

Also, you would think that it’s a good idea, for a contract to self-destruct itself, so you can clean the
blockchain, but a contract that was destroyed will remain on the blockchain, and could always receive
ether as outlined above.

You should also think about a “plan b”, if for some reason, your contract doesn’t behave as expected
during production. Because you can’t modify a smart contract once it’s deployed, you may want to keep a
sort of lock you can trigger, and it can either pause the transactions of the contract, or send the value it
holds to another contract that’ll let the users of the contract withdraw their ether for example. That
trigger diminish the decentralization of the contract by giving power to a third party, so it will depend on
the use case of your contract, to whether or not use such a system.

Security
Security on Solidity starts by following common development patterns, staying up to date with the
development of the platform, making your contract bugs free(or at least trying to) through tests,
knowing the limitations of the platform, keeping your contract code as simple as possible, and keeping in
mind that Ethereum itself(The software behind the blockchain, Solidity compiler etc.) has bugs, and is
changing everyday.

Tests
Tests are an important part of any serious development, and if your old methods included waiting for the
bugs to show up before Exing them, you are going to have a hard time adapting.

Tru[e, that we saw in the last part, let us test our contracts in an easy way.

Open the project of the last part, Ere a couple command-line interfaces, and launch ganache-cli.

ganache-cli -p 7545

Create a new folder named “test”, and create a Ele named “TestExample.js” inside.
Paste the following content in it:

1 var Wrestling = artifacts.require("Wrestling");


2
3 contract('Wrestling', function(accounts) {
4
5 // "it" is the block to run a single test
6 it("should not be able to withdraw ether", function() {
7 Wrestling.deployed().then(function (inst) {
8 // We retrieve the instance of the deployed Wrestling contract
9 wrestlingInstance = inst;
10
11 var account0 = accounts[0];
12
13 // how much ether the account has before running the following tran
14 var beforeWithdraw = web3.eth.getBalance(account0);
15
16 // We try to use the function withdraw from the Wrestling contract
17 // It should revert because the wrestling isn't finished
18 wrestlingInstance.withdraw({from: account0}).then(function
19 assert(false, "should revert");
20 }).catch(function (err) {
21 // We expect a "revert" exception from the VM, because the
22 // should not be able to withdraw ether
23 console.log('Error: ' + err);
24
25 // how much ether the account has after running the transac
26 var afterWithdraw = web3.eth.getBalance(account0);
27 var diff = beforeWithdraw - afterWithdraw;
28
29 // The account paid for gas to execute the transaction
30 console.log('Difference: ' + web3.fromWei(diff, "
31 })
32 })

What it does is, retrieve the Wrestling contract, deploy it to our test network, and try to use the withdraw
function. Because no one should be able to use the withdraw function before the game ends, it should
return an error because of the “require” instruction we used inside the withdraw function in our contract.

Execute the test on the development console:


truffle test --network development

You should have a similar output to this:

Because executing contract functions is an asynchronous process, you would prefer to use async/await
for a cleaner test code. But for the sake of simplicity, our example does the job.

An exercise for you would be to simulate a wrestling game, and make sure only the winner can withdraw
the ether oY the contract at the end (pretty much like we did with the tru[e console in the last part).

You can see another example of testing in this tutorial. And, don’t hesitate to check Tru[e’s
documentation.

Alternatively, there are some security tools made by the community that can help you when you audit
your code. They are listed here.

Business logic
Testing the functions inside the contract is good, but you should always step backward, and see the
interaction between the functions inside your contract, and if you contract, as a whole, is doing what it
should do (And nothing else).

Keeping your smart contract well-commented is the Erst step toward a clear, and well-written piece of
code (note that the Wrestling.sol contract we saw in the Erst part is not). The second step would be to
keep your contract as simple as possible, and only write in the smart contract the part of your application
that needs to be decentralized. If your smart contract will be part of a Dapp (in simple words, a dapp is a
web application that have a part of it decentralized* (i.e: A part of it is a smart contract, or it interacts
with smart contracts)), make the diYerence between what needs to be on the blockchain, and what can
be handled by the UI, or the backend of the web app.
Note*: The deEnition of a dapp is broader than that, and includes all applications that leverage peer-to-
peer interactions. Mist, Bittorrent, Tor etc. are all application that can be called decentralized. See this
article by Vitalik Buterin.

Know the platform


To really know what you are doing, you should read the docs, there is no way around it, and complete
your knowledge by searching on aspects of Solidity development that are not covered in the docs.

For example, you should know that Exed-point variable (a.k.a. ?oats or double) are not fully
implemented yet, and a division using the the type “uint”, like 7 / 3, will round down to the nearest
integer, in this case 2. So you should not take for granted some things on a platform that is still under
heavy development.

Because the blockchain is public, everyone could know the information that your variables hold, and you
could only try to obfuscate the information within, and not conceal it completely. Same thing for
generating a random number or string, anyone who knows how you’ll try to generate the number could
potentially craft it. There are actually people trying to Egure out the best method to generate random
numbers, and you may want to join the Eght if that interests you. As I said before, everything is still
under development, and there is no industry standards for a lot of things.

Time dependent contracts are also a hot point, if your contract would need to run at certain times, you
would need to rely on an external application (and keep in mind that it can go down or cease to function
at a certain time), because a smart contract cannot trigger itself. If your contract rely on time to judge on
certain points, remember that malicious miners could temper with the time a transaction will be
executed.

Know also that your contract is public, everyone can read it, everyone can interact with it, and if your
contract interact or make external calls to other contracts, you have to keep in mind that a malicious
contract could temper with the execution of yours.

All of this become a bit James Bondy, but when there is a lot of money at stake, people get creative. If
your smart contract is running behind a store that sells diapers for old people, you probably wouldn’t
need to care that much.

Limitations of the platform


Know that the Ethereum platform is not meant for heavy computations, and your transactions are limited
by gas. You should keep the logic as simple as possible, and beware of inEnite loops, storage limits, value
over?ow, and all of these little details. Because you can’t remove or modify a contract once it’s on the
blockchain, you should consider all these aspects before deploying it.

The compiler, and the software behind the Ethereum blockchain are still under development, and
undergo continual change, so you should keep that in mind, and stay up to date.

Third parties
There a lot of good actors trying to make the users and developers life easier, and let them access the
Ethereum main blockchain without the need to download it locally. Such as MEW, that let you transfer
ether and deploy smart contracts, or INFURA that let you access Ethereum blockchain through an API,
which is, coupled with tru[e, is a solid tool.

While there is no doubt about the good intentions of these services, and the skills of the developers
behind them, it’s up to you to whether or not seek convenience over security. Platforms like that are
always the target of hackers because of the number of transactions they handle, so they will be always a
bigger target than a node you set on your machine. At the end, your choice will depend largely on how
much money you are moving around and juggling with.

Some directions, and where to start


Before leaving you, here are some great materials where you can start your research:

• A great alternative introduction, in video, would be this one from @KonstantHacker.

• Common patterns on Solidity docs.

• Security considérantions on Solidity docs.

• A more exhaustive document regrouping more recommendations.

One thing to keep in mind is, no document can be complete when it comes to security, so you have to
research on your own, and use well-thought out and good programming practices.

And most of all, start participating, there a lot of project that would need more eyes to End bugs in their
code, and there a lot of bounties to grab.

And if you End a bug, or discover a better way to do something, don’t hesitate to share your knowledge.
Ethereum and the blockchain world follow the open source principles, so the whole community beneEt
from whatever is discovered or made.
The code for this part is available on Github.

devzl/ethereum-walkthrough-3
ethereum-walkthrough-3 - Repository for the third part of the
tutorial series on Ethereum, "Ethereum development…
github.com

Conclusion
As a conclusion, you really need to get that mindset of a smart contracts developer, and prepare to do a
lot of research and tests before launching your contracts into the wild.

And as professor Moody says:

If you liked this third part, you can End me @dev_zl.

In the next part we will see tokens.


If this is the Grst article that you read on Ethereum or the blockchain eco-system in general, you are
going to love it! Experts calling each others names on twitter, unsafe standards and protocols, untested
and buggy development tools. Not everything is Ggured out yet, everyone is going in diKerent directions,
and there still a lot to be done. The future of institutions, banks, and governments is being decided by
mad developers! It’s so great.

Anyway, don’t worry anymore, I’ll try to connect all the dots for you in this tutorial series, and walk you
through the universe of Smart contracts and dapps developement, and show you how everything Gts
together.

While I will not get into every detail, I’ll link some materials that will help you understand some concepts
better, and it’s up to you to research them and get into all the little details. The goal of this series is to
help you understand better how things work together, in the simplest way possible, like a friend would
explain it to you.

I don’t even know what Ethereum is


The oNcial website of Ethereum tells us this:

Ethereum is a decentralized platform that runs smart contracts: applications that run exactly as
programmed without any possibility of downtime, censorship, fraud or third-party interference.

In other words, it uses the capabilities that gives us the blockchain technology to certify the execution of
the code that we run.

If you don’t know what the blockchain, Ethereum, Bitcoin, cryptocurrency or any of these words mean, I
advise you to listen to this excellent podcast by Tim Ferriss, interviewing Nick Szabo and Naval Ravikant:
The Quiet Master of Cryptocurrency — Nick Szabo

What are Smart Contracts?


On Ethereum, Smart Contracts are scripts that can handle money. It’s as simple as that.

These contracts are enforced and certiGed by parties that we call miners. Miners are multiple computers
who add a transaction (Execution of a smart contract, payment of a cryptocurrency etc.) to a public
ledger that we call a block. Multiple blocks constitute a blockchain.

We pay these miners with something called Gas, which is the cost to run a contract. When you publish a
smart contract, or execute a function of a smart contract, or transfer money to another account, you pay
some ether that gets converted into gas.

If it’s still unclear, or you want to know more details, here are some interesting links:

• A diKerent introduction to Smart Contracts in video.

• Smart contracts page on Wikipedia.

• A more detailed explanation of Gas.

Before diving into smart contracts development


In this tutorial, I’ll assume that you already have some basis in software development, and have a basic
knowledge of Javascript and Node.JS. Otherwise, you’ll be quickly lost. Solidity, the programming
language that we will use to develop, is close to Javascript’s syntax, and since a lot of development tools
around Ethereum are based on Javascript and NodeJS, it will be easier for you to get in if you are already
comfortable with both. This is not a tutorial for beginners, and while I’ll link some alternative tutorials for
you if you didn’t understand some concepts, it’s up to you to research the rest.

Smart contracts development


Now, Gnally, we start the interesting part, as I said Solidity is close to Javascript, but they are not alike.
On Solidity, and I’m sorry to tell you that, frontend developer, you just can’t slap JQuery on a piece of
code and hope that it will work, you can’t overlook security, and you just can’t hack your way through.
We will see why when we will discuss security, development patterns, and fail-prooGng our code.

Now, for our Grst example, I’m thinking about a script inspired by the movie In Time, where, in a
dystopian future, people trade their remaining time to live like money. In the movie, they have a variant
of arm wrestling that involves playing with that time, and we will do just that! Wrestling money using a
Smart Contract.
And don’t worry, I’ll make available for you all the scripts we will see on Github.

Also, if it’s the Grst time you deal with smart contracts, it’s Gne if you don’t understand everything now, it
takes practice, reading the docs, and a bit of research to get accustomed to Solidity.

The code
Now, onto the coding, Grst of all, the base of a Solidity script is the following snippet, the pragma
directive to tell the compiler which version of Solidity we are using, and the name of our contract, a
similar structure to a class in Javascript. Here it’s “Wrestling”.


1 pragma solidity ^0.4.18;
2
3 contract Wrestling {
4 // our code will go here
5 }

Wrestling.sol hosted with by GitHub view raw

We want two wrestlers, so we will add two variables that hold the address of their accounts (Public keys
of their wallets).

1 address public wrestler1;
2 address public wrestler2;

Wrestling.sol hosted with by GitHub view raw

In our little game, in each round, the wrestlers will be able to put in a sum of money, and if one put in
double the money of the other(in total), he will win.


1 bool public wrestler1Played;
2 bool public wrestler2Played;
3
4 uint private wrestler1Deposit;
5 uint private wrestler2Deposit;
6
7 bool public gameFinished;
8 address public theWinner;
9 uint gains;

Wrestling.sol hosted with by GitHub view raw

One important thing about the public/private keywords is, even though, a variable is private, it doesn’t
mean that someone couldn’t read its content, it just means that it can be accessed only inside the
contract, but in reality, since the whole blockchain is stored on a lot of computers, the information that is
stored inside the variable could always be seen by others, and that represents the Grst security
consideration that you should keep in mind.

On the other hand, the compiler automatically creates getter functions for public variables. To make it
possible for other contracts or users to change the value of the public variable, you need to create a setter
function.

Now we will add three events, for every step of our game. The beginning, when the wrestlers register,
during the game, for each round, and at the end, when a wrestler wins. Events are simply logs, and they
can be used to call JavaScript callbacks in the user interface of distributed applications, also known as
dapps. Events can even be used for debugging purposes during development since there is no equivalent
to the “console.log()” function of JavaScript on Solidity.


1 event WrestlingStartsEvent(address wrestler1, address wrestler2);
2 event EndOfRoundEvent(uint wrestler1Deposit, uint wrestler2Deposit);
3 event EndOfWrestlingEvent(address winner, uint gains);

Wrestling.sol hosted with by GitHub view raw


Now we will add the constructor, in Solidity, it has the same name as our contract and it will be called
only once, upon the creation of the contract.

Here, the Grst wrestler will be the one who created the contract. “msg.sender” is the address of the one
who invoked the function.


1 function Wrestling() public {
2 wrestler1 = msg.sender;
3 }

Wrestling.sol hosted with by GitHub view raw

Next we let another wrestler register with the following function:


1 function registerAsAnOpponent() public {
2 require(wrestler2 == address(0));
3
4 wrestler2 = msg.sender;
5
6 WrestlingStartsEvent(wrestler1, wrestler2);
7 }

Wrestling.sol hosted with by GitHub view raw

The require function is a special error-handling function within Solidity that will revert changes if a
condition is not met. In our example, if the variable wrestler2 equals the 0x0 address (the equivalent of 0
for addresses), we can proceed, if the address wrestler2 is diKerent from the 0x0 address, it means that a
player has already registered as an opponent, and therefore, we will refuse new registrations.

Again, “msg.sender” is the address of the account that called the function, and we emit an event that
signals the start of the wrestling.

Now, every wrestler will call a function, “wrestle()”, putting in money. And if both have played, we see if
one of them has won (our rule was that one of them have to put in double the cash of the other one). The
“payable” keyword means that the function can receive money, if it isn’t set, the function will not accept
ether. The “msg.value” is the amount of ether that was sent to the contract.

1 function wrestle() public payable {
2 require(!gameFinished && (msg.sender == wrestler1 || msg.sender == wrestler2));
3
4 if(msg.sender == wrestler1) {
5 require(wrestler1Played == false);
6 wrestler1Played = true;
7 wrestler1Deposit = wrestler1Deposit + msg.value;
8 } else {
9 require(wrestler2Played == false);
10 wrestler2Played = true;
11 wrestler2Deposit = wrestler2Deposit + msg.value;
12 }
13 if(wrestler1Played && wrestler2Played) {
14 if(wrestler1Deposit >= wrestler2Deposit * 2) {
15 endOfGame(wrestler1);
16 } else if (wrestler2Deposit >= wrestler1Deposit * 2) {
17 endOfGame(wrestler2);
18 } else {
19 endOfRound();
20 }
21 }
22 }

Wrestling.sol hosted with by GitHub view raw

We then add the endOfGame(), and endOfRound() functions. The “internal” keyword is the same as
private, the only diKerence is that internal functions could be inherited by other contracts(since Solidity
is similar to other object-oriented languages), while private functions cannot be inherited.

1 function endOfRound() internal {
2 wrestler1Played = false;
3 wrestler2Played = false;
4
5 EndOfRoundEvent(wrestler1Deposit, wrestler2Deposit);
6 }
7
8 function endOfGame(address winner) internal {
9 gameFinished = true;
10 theWinner = winner;
11
12 gains = wrestler1Deposit + wrestler2Deposit;
13 EndOfWrestlingEvent(winner, gains);
14 }

Wrestling.sol hosted with by GitHub view raw

Notice that we don’t deliver the money to the winner directly, while in this case it’s not that important,
since the winner will take all the money oK this contract, in other cases, when multiple users can
withdraw ether oK a contract, it’s more secure to use a withdraw pattern, to avoid re-entrancy.

It simply means, that if for example multiple users can withdraw money oK a contract, one can simply
call the withdraw function multiple times at once and get payed multiple times. So we need to write our
withdraw function in such a manner that it will nullify the amount he should receive before proceeding
to pay him.

It looks like this:


1 function withdraw() public {
2 require(gameFinished && theWinner == msg.sender);
3
4 uint amount = gains;
5
6 gains = 0;
7 msg.sender.transfer(amount);
8 }

Wrestling.sol hosted with by GitHub view raw


And that’s it. You can Gnd the whole snippet at the following link:

devzl/ethereum-walkthrough-1
ethereum-walkthrough-1 - Repository for the Irst part of the
tutorial series on Ethereum, "Ethereum development…
github.com

Using an IDE
Copy the snippet now, and open the Remix IDE in a new tab of your browser:

You can use Remix directly on your browser, and it has a lot interesting functionalities that you could
hardly Gnd elsewhere at the moment.

Click on the button “+” on the top left of the page and create a new Gle named “Wrestling.sol”, then past
the code that you can Gnd in the github repo linked above:

Finally some syntax highlighting. Github doesn’t support Solidity .sol extension yet.
On the right part of the page, you can Gnd multiple interesting tabs such as the “Analysis” one, that will
show errors and recommendations. I leave you to discover this tool more. I wanted to show it to you,
even though we will use other tools in the next part, the goal of this tutorial series, as I said before, is to
connect the dots for you, and show you how things Gt together, and it’s up to you to decide whether or
not you are at ease using an IDE on a browser. Invite you to read the docs of Remix if you do.

Alternatively, you should start getting familiar with solidity by reading its docs.

In the next part, we will see how to deploy the Smart Contract to two kinds of test networks, discover
truEe, ganache, and geth, and how they can all Gt together.

If you liked this Grst part, you can Gnd me on twitter @dev_zl.

Part two can be found here.


dev_zl Follow
Dapps, web, and games developer. Interested in AI, blockchain, and smart contracts. You can
reach me at ledevzl@gmail.com or @dev_zl
Jan 15 · 11 min read

Ethereum Development Walkthrough (Part 2: Tru8e,


Ganache, Geth and Mist)

We have seen in the +rst part of this tutorial series what a smart contract is, and how it works. Now, we
will deploy it to two kinds of test networks.

The tools we will use


The most prominent tools at the moments are:

• Tru=e: A development environment, testing framework and asset pipeline for Ethereum. In other
words, it helps you develop smart contracts, publish them, and test them, among other things. You
can read the docs of the Tru=e suite for more informations.

• Ganache: It was called TestRPC before, if you have read a tutorial from a few months ago, chances
are they use TestRPC with Tru=e, but it was renamed upon the integration of TestRPC within the
Tru=e Suite. What Ganache does is simple, it creates a virtual Ethereum blockchain, and it
generates some fake accounts that we will use during development.

• Mist: It’s a browser for decentralized web apps. It seeks to be the equivalent of Chrome or Firefox,
but for Dapps. It’s still insecure and you shouldn’t use it with untrusted dapps as of yet.
• Ethereum wallet: It’s a version of Mist, but only opens one single dapp, the Ethereum Wallet. Mist
and Ethereum Wallet are just UI fronts. And we need a core that will connect us to an Ethereum
blockchain(It could be the real Ethereum blockchain, or a test one).

• Geth: Is the core application on your computer that will connect you to a blockchain. It can also
start a new one (in our case we will create a local test blockchain), create contract, mine ether etc.

We will start by using Tru=e and Ganache, and then use Tru=e with geth and Mist.

Installations
The requirements for this tutorial are that you know what is and how to use a command-line tool, and
you are a bit familiar with NPM.

Tru8e
Open up a command-line, and type the next part:

npm install -g truffle

If something goes wrong I advise you to read more on Tru=e’s docs.

Ganache
Then, install Ganache’s command-line interface:

npm install -g ganache-cli

If you are unsure about something, here is Ganache’s Github page.

N.B: There is a GUI for Ganache, but because we are such haxors, we will use the CLI.

Let’s start
First, create a new folder, and type the next line:

truffle init

It will initialize an empty tru=e project.

Then copy the Wrestling.sol +le from the last tutorial, into the folder “contracts”.

Next, open the folder “migrations” and create a new +le named “2_deploy_contracts.js”. Migrations are
simply scripts that’ll help us deploy our contracts to a blockchain.

Paste the following code inside, and save.


1 const Wrestling = artifacts.require("./Wrestling.sol")
2
3 module.exports = function(deployer) {
4 deployer.deploy(Wrestling);
5 };

2_deploy_contracts.js hosted with by GitHub view raw

The +rst line is there to import the “Wrestling.sol” +le from the “contracts” folder, and the 4th line
deploys it to the blockchain.

Now, back to the root folder, you’ll see two +les, “tru=e.js” and “tru=e-con+g.js”. If you are on Windows,
remove “tru=e.js”, if you are on another system, remove one of them, or keep them both, it’s not
important. The reason for that is, on Windows there is a naming problem, and when we will want to
execute Tru=e commands, it will open the con+g +le “tru=e.js” instead of reading what’s inside.

I’m writing this tutorial on Windows, so I’ll remove the “tru=e.js” +le. Then I’ll put this code inside of
“tru=e-con+g.js”:

1 module.exports = {
2 // See <http://truffleframework.com/docs/advanced/configuration>
3 // for more about customizing your Truffle configuration!
4 networks: {
5 development: {
6 host: "127.0.0.1",
7 port: 7545,
8 network_id: "*" // Match any network id
9 }
10 }
11 };

truffle-config.js hosted with by GitHub view raw

It basically says, that, when using the development network, connect to the host at “127.0.0.1”
(localhost), using the port 7545.

Now we are ready to test our code on a blockchain!

Testing our code


In the +rst part, we will use Ganache.

Fire a new command-line and type in the following command:

ganache-cli -p 7545

What it does is, it tells ganache-cli to start at the port 7545.

Ganache will generate test accounts for us, they have 100 ether by default, and are unlocked so we can
send ether from them freely. The +rst account for example is the guy right here:
Now, back to our +rst command-line interface, we execute two commands:

truffle compile
truffle migrate --network development

Compile will compile our Solidity code to bytecode (the code that the Ethereum Virtual Machine (EVM)
understands), in our case, Ganache emulates the EVM.

Migrate will deploy the code to the blockchain, in our case, the blockchain could be found in the network
“development” we set earlier in the “tru=e-con+g.js” +le.

Now, if everything has gone as expected, you should see this on your terminal:
Notice that it shows the address of the instantiated Wrestling contract.

On the commande-line interface where ganache-cli is run, you can see the transactions being executed:

Notice that it shows the address of the instantiated Wrestling contract.

Now type the following command to start Tru=e’s console. It will help us interact with ganache’s
blockchain.

truffle console --network development

First, we will execute this commands:


account0 = web3.eth.accounts[0]
account1 = web3.eth.accounts[1]

It will assign the address of the +rst account to the variable account0, the second to the variable
account1. Web3 is a JavaScript API that wraps RPC calls to help us interact with a blockchain in an easy
way.

Then we will write this:

Wrestling.deployed().then(inst => { WrestlingInstance = inst })

It assigns a reference to the instance of the contract that tru=e deployed to the variable
“WrestlingInstance”.

Execute the the next line:

WrestlingInstance.wrestler1.call()

It will return the address of the wrestler1, in our case it was the +rst account. Tru=e, during the
migration, picked up the default account from Ganache, which is the +rst account, because we didn’t
specify another account address during the migration, or another address in the con+guration +le of
Tru=e.

We will then register the second account as an opponent:

WrestlingInstance.registerAsAnOpponent({from: account1})

Here, the “from” directive tells the function from which account the transaction should be +red.

Upon executing the line, it should return something similar to this:


Notice that the transaction used Gas, and it +red the event “WrestlingStartsEvent”.

You could retrieve the address of the second wrestler by executing the following line:

WrestlingInstance.wrestler2.call()

Now, the players can wrestle:

WrestlingInstance.wrestle({from: account0, value: web3.toWei(2, "ether")})


WrestlingInstance.wrestle({from: account1, value: web3.toWei(3, "ether")})

// End of the first round

WrestlingInstance.wrestle({from: account0, value: web3.toWei(5, "ether")})


WrestlingInstance.wrestle({from: account1, value: web3.toWei(20, "ether")})

// End of the wrestling

The “value” directive is used to send ether with a transaction. The “web3.toWei(5, “ether”)” part sends 5
ether, that value is converted to Wei. Wei is the base unit (lowest denomination) of ether. More infos
could be found at this link.
Upon executing the last line, the account1 will be the winner, since we put 23 ether in total with it, and
it’s more than the double of what we put with the account0.

A little exercise for you is to withdraw the ether from the contract.

Now, it’s up to you to research how to use Tru=e’s and Ganache’s advanced features. You can start by
reading the docs, and alternatively, here is an excellent introduction to Tru=e if you felt lost or want to
reinforce your knowledge on what we just saw.

How geth will Ft in the picture


Now, if we used Ganache for development, we would want to use something closer to a real
environment, if only just to be more familiar with it.

Installations
Start by downloading geth. On Windows, you might need to add geth’s installation folder to your PATH
variable.

Download Mist or Ethereum Wallet. For our use, both will be alike, so it doesn’t matter which one you
pick.

Onto the creation of the local private test network


In the same root folder, create a new +le, and name it “genesis.json”. Then past the following content in
it.

1 {
2 "difficulty" : "0x20000",
3 "extraData" : "",
4 "gasLimit" : "0x8000000",
5 "alloc": {},
6 "config": {
7 "chainId": 15,
8 "homesteadBlock": 0,
9 "eip155Block": 0,
10 "eip158Block": 0
11 }
12 }

genesis.json hosted with by GitHub view raw

The +le “genesis.json” is simply the con+guration +le that geth needs to create a new blockchain. It’s not
important to understand the content of the +le for the moment.

If you run geth without specifying any parameter, it will try to connect to the mainnet. The mainnet is the
main network of Ethereum, the real blockchain of Ethereum.

If you run Mist without speci+ying any parameter, it will throw an error if an instance of geth is running.
If you tell Mist to connect to the geth instance that is actually running(what we will do in a little
moment) it’ll work just +ne. If you run Mist while no instance of geth is running, it will start a new
instance of geth, and eventually ask you from which blockchain network it should download blocks.

There is a public Ethereum test network, but we will create our own private test network locally, using
the “genesis.json” +le we created earlier.

Fire up another command-line interface and type in the following (be sure to run it in your project root
folder):

geth --datadir=./chaindata/ init ./genesis.json

We launch geth and specify where our blockchain will be stored, here in the “chaindata” folder (it will be
automatically generated), and we initialize it with our “genesis.json” con+guration +le.

We then start geth using the following command:


geth --datadir=./chaindata/ --rpc

The “--rpc” parameter tells geth to accept RPC connections, it’s needed so that tru=e can connect to geth.

Open another command-line interface, and start Mist (or Ethereum Wallet), using the same parameters:

mist –rpc http://127.0.0.1:8545

The “-rpc” tells Mist (or Ethereum Wallet) to connect to the instance of geth we started.

In the Wallets tab, press Add Account and create a new wallet:

Notice that we are using a private network. Beware of that, you wouldn’t want to use you ether on the
Mainnet for development purposes.
I will create an account using the password “123456789”. In a real environment, use a stronger
password.

Open up a new command-line interface and run this command:

geth attach

It will run the console of geth, and we can now interact with it.

With out main account created on the Mist UI, we will run this command inside of “geth attach” console:

miner.start()

It will start a miner, the process that will con+rm transactions, and after a few seconds or minutes
(depending or your computer), you should start seeing ether being added to your balance (And also to
your main account):
Note that if you don’t have enough RAM available, it may not start mining at all. You can stop the mining
using the command “miner.stop()”.

Now, open the “tru=e-con+g.js” +le again, and modify it like this:


1 module.exports = {
2 // See <http://truffleframework.com/docs/advanced/configuration>
3 // for more about customizing your Truffle configuration!
4 networks: {
5 development: {
6 host: "127.0.0.1",
7 port: 7545,
8 network_id: "*"
9 },
10 ourTestNet: {
11 host: "127.0.0.1",
12 port: 8545,
13 network_id: "*"
14 }
15 }
16 };

truffle-config.js hosted with by GitHub view raw


The “ourTestNet” is the con+guration necessary to connect to the geth instance. Geth starts by default on
port 8545.

In the command-line interface where we launched “geth attach”, we will unlock the account, so we can
use it to migrate the Smart Contract from Tru=e, using the following command:

personal.unlockAccount('0x6AC4660c960Aaf5d9E86403DDAcB4791767e5869', '123456789')

Here, I used the address of the account I just created, it would be a dijerent address for you, and the
password “123456789” that I’ll use for these tests. Notice that the password is shown in plain text, and
you should use a dijerent method with a real account.

Now, back to the command-line interface where we previously launched Tru=e, run this command:

truffle migrate --network ourTestNet

It will start migrating the contract to the blockchain that geth is running. Start the miner if you
previously stopped it, otherwise, the migration will not be executed.

If the migration was successful, you would see an output like this:
Now, run the following command to start Tru=e’s console:

truffle console --network ourTestNet

Then run these two commands:

Wrestling.address
JSON.stringify(Wrestling.abi)

You should have an output like this:

The +rst line returns the address of the deployed Wresting contract instance.

The second line, will return the Wresting contract ABI. The ABI is basically a description of the contract.
It contains a list of its functions and variables among other things.

When copying the address and the ABI, remove the apostrophes highlighted by a red arrow in the screenshot.

Now, back to Mist, we will open the contracts tab, and click on watch contract.
Then we will past the address and the ABI of the Wrestling contract we deployed:
Click on “OK”, then it will be shown in your watched contracts list. Click on it and it will open the
contract page. If you scroll down, you’ll see something like this:
Use the select a function part to interact with the contract. It’s the same as we did above using Tru=e’s
console.

And that’s it, we saw how Ganache and geth come in play. When you will want to deploy a contract to the
real blockchain, you should use the second method and connect geth with the mainnet.

N.B: You could deploy a contract directly on Mist without using Tru@e migration system, here is an example
video of that process. Using Tru=e is more interesting in a real development process though, since you’ll
be able to include and import multiple other smart contracts and scripts if you use a modular approach to
develop your smart contracts.

N.B.2: You could always write your contract code on a basic nodepad application, and deploy it to the
mainnet using some trusted third party’s portal, but I advise you to not.

The repository for this tutorial can be found here:

devzl/ethereum-walkthrough-2
ethereum-walkthrough-2 - Repository for the second part of the
tutorial series on Ethereum, "Ethereum development…
github.com
In conclusion
We have seen 4 ways of developing and deploying our Smart Contracts:

• The +rst one is to use Tru=e and Ganache. Since we copied the code from the last tutorial, I want to
tell you that there are plugins available for the most popular text editors and IDEs. Some ojer only
syntax highlighting, while others help with other areas.

• The second one is to deploy code from Tru=e to geth (and the GUI app Mist).

• The third, is to use Remix to write small, simple contract when you are just learning Solidity, and
deploying the code in Mist like shown in the video previously linked.

• Or like a real cowboy, you could use a simple text editor to write and then deploy your untested
contract using a nameless third party’s drag-and-drop deployment feature.

In the next part, we will discuss security since our “Wrestling” script is far from being ready to be
launched in a real environment.

After, that we will see Token creation, and Initial Coin Ojerings (ICOs).

If you liked this second part, you can +nd me on twitter @dev_zl.

Вам также может понравиться